溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Jira任務管理系統(tǒng)項目實例分析

發(fā)布時間:2022-08-31 09:49:56 來源:億速云 閱讀:181 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“Jira任務管理系統(tǒng)項目實例分析”,在日常操作中,相信很多人在Jira任務管理系統(tǒng)項目實例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Jira任務管理系統(tǒng)項目實例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

跨組件狀態(tài)管理

簡單場景

對于不復雜的情況,比如父組件傳遞狀態(tài)給子組件,可以使用 props 進行傳遞。如果需要傳遞的狀態(tài)過多,我們還可以使用組合組件的方法將子組件內的部分組件提升到父組件中去,這樣就不需要再一層層的傳遞狀態(tài)了

服務端狀態(tài)

對于服務端狀態(tài)的維護,也就是發(fā)送網(wǎng)絡請求才能獲取到的數(shù)據(jù),如果這些數(shù)據(jù)需要在多個組件中共享,以前可能很多人會選擇用 contextredux 來管理服務端的狀態(tài),但這樣會導致他們所維護的狀態(tài)樹過重,不利于項目的維護。

不過隨著 react-queryswr 這些庫的火爆,越來越多的人愿意使用它們來管理服務端的狀態(tài),除了管理狀態(tài)以外,他們還可以對我們的項目做一些優(yōu)化,比如 react-query 可以避免重復發(fā)送相同的請求、以及方便實現(xiàn)樂觀更新等操作

客戶端狀態(tài)

對于復雜的客戶端狀態(tài)來說,我們一般有幾種方法來管理,一是通過網(wǎng)頁的 url,這種方式可以有效的管理較少的狀態(tài)。二是通過傳統(tǒng)的 redux,但是大部分的項目其實并沒有那么多的全局狀態(tài)要管理,如果都使用 redux 進行管理的話,反而會讓整個項目顯得笨重很多,所以,隨著 react hooks 的火爆,contex 結合 hooks 慢慢成為了項目中狀態(tài)管理的主流

項目初始化

  • 使用 React 官方提供的腳手架 create-react-app 來初始化 React + TS 項目

  • 使用統(tǒng)一的代碼格式化工具 prettier(www.prettier.cn/docs/instal…),這樣你的團隊成員無論使用什么 IDE 和插件,格式化項目的時候效果都是一樣的,不容易產生分歧

  • 配置 commitlint 幫助我們檢查每次 git commit 的信息是否符合規(guī)范,如果不符合就讓本次提交失敗,這回讓團隊協(xié)作的效率更高,項目的可維護性也會更強

Mock 方案

  • 直接在代碼中寫死 Mock 數(shù)據(jù),或者請求本地的 JSON 文件

  • 請求攔截向后端發(fā)送的請求,比如使用 Mock.js 來模擬數(shù)據(jù)

  • 使用接口管理工具來 mock 數(shù)據(jù),比如 apipost、yapi 等等,但前提項目是文檔先行而不是代碼先行

  • 自己用 node 開啟一個本地服務器,也可以借助一些好用的庫,比如 json-server

錯誤邊界

錯誤邊界是一種 React 組件,這種組件可以捕獲發(fā)生在其子組件樹任何位置的 JavaScript 錯誤,并打印這些錯誤,同時展示降級 UI,而并不會渲染那些發(fā)生崩潰的子組件樹。

錯誤邊界可以捕獲發(fā)生在整個子組件樹的渲染期間、生命周期方法以及構造函數(shù)中的錯誤。

useState 的惰性初始化

當參數(shù)是函數(shù)的時候,useState 幫我們保存的狀態(tài)并不是該函數(shù),而是其返回值,為了獲取到該返回值,react 會在組件第一次渲染的時候執(zhí)行該函數(shù),后續(xù)組件的重復渲染中,該函數(shù)就不會再被執(zhí)行了,所以這種初始化 state 的方法也叫作惰性初始化,其適用于初始 state 需要通過復雜計算才能獲得的情況。所以如果想用 useState 保存函數(shù),不能直接傳入函數(shù),而是需要多嵌套一層函數(shù)

樂觀更新

客戶端假設請求必然成功,因此不等待接口的返回,先行對視圖進行更新,隨后再根據(jù)請求返回的結果調整數(shù)據(jù),如果請求是成功的,則不改變提前更新好的 UI;如果請求失敗了,則需要將數(shù)據(jù)和 UI 視圖回滾至請求前的狀態(tài)并用此時數(shù)據(jù)庫中的準確數(shù)據(jù)代替

性能追蹤

Profiler 測量一個 React 應用多久渲染一次以及渲染一次的“代價”。 它的目的是識別出應用中渲染較慢的部分,或是可以使用類似 memoization 優(yōu)化的部分,并從相關優(yōu)化中獲益

性能追蹤是我們在開發(fā)項目時經常會被忽略的一個問題,React 恰好為我們提供了用于性能追蹤的一個 API—Profiler,它的用法很簡單,只需要嵌套在組件外部就可以知道該組件渲染所花費的時間,很方便幫助我們去定位哪些組件需要被優(yōu)化

自動化測試

很多時候我們都需要對原先的項目添加新的功能,相信很多人都會遇到添加了新功能后,原先的功能卻出現(xiàn) bug 的情況,以至于我們每次加一個功能都還需要手動檢查原先的功能有沒有被影響

自動化測試就可以很方便的解決剛剛的問題,每當代碼更改都會使用我們預先寫好的代碼測試原先的函數(shù)、hook、組件、頁面是否能夠正常工作,返回我們想要的結果,這樣我們開發(fā)完新功能之后就不用在手動的去測試了,不過由于這一塊知識點難度較大,所以我也只是做了一個簡單的了解~

Q & A

1. 如何實現(xiàn)頁面刷新后持久化存儲用戶信息?

在正常的項目中,我們可以先在本地保存用戶的 token 和用戶信息,每當用戶初始化頁面時,我們就判斷用戶的瀏覽器本地是否存有 token,如果沒有則直接跳轉到登錄頁面;如果有則先展示本地存儲的用戶信息,然后根據(jù) token 查詢數(shù)據(jù)庫中最新的用戶信息并更新到本地

2. 如何在不同路由組件中實現(xiàn)網(wǎng)頁標題的切換?

網(wǎng)上已經針對該問題給出了很多的解決方案,比如可以使用 react-helmet 這個庫,不過我們也可以自己實現(xiàn):使用原生的 doucument.title 來控制標題的變換。為了增強該功能的復用性,我們可以將其封裝成一個自定義 hook 在不同的組件中使用

export default function useDocumentTitle(title: string, keepOnUnmount: boolean = true) {
  // 保存當前路由對應的標題
  const oldTitle = useRef(document.title).current
  useEffect(() => {
    // 當該組件掛載到頁面中時,將開發(fā)者指定的文本替換成網(wǎng)頁標題
    document.title = title
    // 根據(jù)傳入該函數(shù)的參數(shù)來決定組件卸載時是否回滾到先前的網(wǎng)頁標題
    return () => {
      if (!keepOnUnmount) document.title = oldTitle
    }
  }, [oldTitle, keepOnUnmount, title])
}

3. 如何避免無限渲染問題?

我們盡量控制傳遞給 useEffect 的依賴項數(shù)組中的變量可以是組件中管理的狀態(tài) state,也可以是 useRef 保存的值或者基本數(shù)據(jù)類型,但一定不能是對象類型的變量,因為不同的對象即使看起來是一樣的但本質上它們的地址卻是不同的,而 react 內部在比較新舊兩個變量時用的是 === 號,在這種情況下,每次組件重復渲染時 useEffect 所比對出的新舊依賴都不相同,從而導致組件無限渲染。所以如果要傳遞普通對象,則該對象一定需要用 useMemo 包裹處理以避免組件無限循環(huán)渲染

4.TS 允許擴展組件的 props

如何在自己封裝的組件以 antd 組件為基礎的情況下,讓 TS 允許擴展組件的 props?

ComponentPropsReact 內置的類型,用于獲取組件的 props 類型,其需要傳遞一個組件(函數(shù)式或類)的類型

import { ComponentProps } from "react";
import { Select } from "antd";
type SelectProps = ComponentProps<typeof Select>;
// 其實上述的方法和下面的是等價的  // type SelectProps = Parameters<typeof Select>[0]
// Parameters 可以獲取函數(shù)的參數(shù)并放置到一個元組中,而 antd 的組件恰好是一個函數(shù),所以 [0] 就表示取出 props 的類型
// 創(chuàng)建自己組件的 props 類型,用好 TS 的內置類型 Omit 來防止一些我們添加的屬性影響到原先 antd 組件的屬性
interface IdSelectProps
  extends Omit<
  SelectProps,
  "value" | "setState" | "defaultOptionName" | "options"
  > {
  value?: Raw | null | undefined;
  setState?(value?: number): void;
  defaultOptionName?: string;
  options?: { name: string; id: number }[];
}
// 在 antd 組件的基礎上再封裝一個組件,使得該組件不僅可以傳遞原先 antd 組件中的參數(shù),還可以傳遞一些我們定義的屬性
export default function IdSelect(props: IdSelectProps) {
  const { value, setState, defaultOptionName, options, ...restProps } = props;
  return (
    <Select
      value={value || 0}
      onChange={(value) => setState?.(toNumber(value) || undefined)}
      // 這個 {} 并不表示對象的意思,不要理解錯了,而是 jsx 語法要求在變量外邊需要套個 {}
      {...restProps}     >
      {defaultOptionName ? (
        <Select.Option value={0}>{defaultOptionName}</Select.Option>
      ) : null}
      {options?.map((item) =>
        item ? (
          <Select.Option key={item.id} value={item.id}>
            {item.name}
          </Select.Option>
        ) : null
      )}
    </Select>
  );
}

5. 文件命名

什么時候將文件命名為 tsx 和 jsx,什么時候又命名為 ts 與 js?

當文件中包含組件的時候用 tsxjsx 后綴命名,其它情況下用 tsjs 命名就可以了。正確的使用文件后綴名可以提高項目的可讀性,當別人一看到該文件的后綴是以 tsx 結尾的,就能立馬知道該文件中包含的是一個組件而不是普通的函數(shù)

6. 什么時候使用組件組合?

Context 主要應用場景在于很多不同層級的組件需要訪問同樣一些的數(shù)據(jù)。請謹慎使用,因為這會使得組件的復用性變差。

如果你只是想避免層層傳遞一些屬性, 組件組合(component composition) 有時候是一個比 context 更好的解決方案。&mdash;&mdash; React 官網(wǎng)

聽起來很高大上的名詞,其實非常簡單,就是在面對一些狀態(tài)需要層層跨組件傳遞時,如果這些狀態(tài)都是集中在某一個區(qū)域里面使用,那么可以把這一塊區(qū)域抽離出一個組件放置到狀態(tài)初始化的地方。這樣原本需要層層傳遞多個狀態(tài),現(xiàn)在就只需要將組件傳遞過去即可。

這種做法還有一個好處就是子組件不需要擔心如何消費上層傳入過來的狀態(tài),只需要將注意力放到渲染傳入進來的組件上,下面是官網(wǎng)給出的示例:

function Page(props) {
  const user = props.user;
  const userLink = (
    <Link href={user.permalink}>
      <Avatar user={user} size={props.avatarSize} />
    </Link>
  );
  return <PageLayout userLink={userLink} />;
}
// 現(xiàn)在,我們有這樣的組件:
<Page user={user} avatarSize={avatarSize} />
// ... 渲染出 ...Page的子組件
<PageLayout userLink={...} />
// ... 渲染出 ...PageLayout的子組件
<NavigationBar userLink={...} />
// ... 渲染出 ...
{props.userLink}

7. 如何將自己的項目部署到 github 上?

  • 新建一個名為 你的github用戶名.github.io 的倉庫

  • 在開發(fā)環(huán)境下安裝 gh-pages 依賴 yarn add gh-pages -D,該庫是 github 專門為開發(fā)者提供用來部署項目的

  • package.json 文件夾中找到 scripts 字段,新加下列代碼中的信息

// 如果你是用 npm 來啟動項目的,也可以修改為 npm run build
"predeploy": "yarn build", 
// 該字段表示的意思為將打包后的 build 文件夾推送到指定倉庫的 main 分支
"deploy": "gh-pages -d build -r 創(chuàng)建的倉庫地址 -b main"
  • 在命令行中執(zhí)行 yarn deploy 命令,其會預先 predeploy 字段對應的命令 yarn build,然后將打包后的內容 push 到指定的倉庫中去,所有操作完成之后打開 github 指定的網(wǎng)頁即可看到你的應用啦!如果后續(xù)需要更新項目,只需要更新代碼后重新執(zhí)行該命令即可

8. 部署 github 頁面報404

部署到 github 上的項目為啥有時刷新頁面會報 404 的錯誤?

假設我們部署在 github 上的地址為 sindu12jun.github.io,由于我們的項目是單頁面應用,里面用的都是前端路由,如果當前 url 變化為了 sindu12jun.github.io/projects,此時&hellip;

Jira任務管理系統(tǒng)項目實例分析

這樣服務端接收到這個 url 對應的請求后會誤認為是服務器路由,其并找不到該 url 匹配的接口,也不會像訪問首頁 url 一樣將 index.html 響應給客戶端,而是返回一個404的頁面

9. 我們的項目是用什么工具把 TS 編譯成 JS 文件的?

可能學習過 TS 的朋友都知道其真正要在瀏覽器或者 node 中被執(zhí)行需要提前編譯成 JS 文件,對于這個編譯工具大家的第一反應可能是 tsc

其實不是, 目前大多數(shù)的 ts 項目都是 ts 類型檢查 + babel 編譯 這樣的組合,這個項目也不例外 (可以去項目 node_modules 下面看一下,會發(fā)現(xiàn)有個 @babel 文件夾),用 babel 編譯 ts,就可以實現(xiàn) babel 編譯一切,從而降低開發(fā)/配置成本

10. 所有的函數(shù)式組件都應該被 React.memo 所包裹嗎?

在子組件沒有經過特殊處理的情況下,父組件由于狀態(tài)改變導致重復渲染時,子組件也會進行重復渲染,但有的時候我們并不想讓子組件進行無用的渲染,這時就會想到在組件外用 React.memo 來包裹

React.memo 會比較函數(shù)式組件前后兩次的 props 是否發(fā)生了變化,比較方法是淺層比較,如果判斷為沒有變化,則組件不會重新渲染,聽起來是一個很不錯的優(yōu)化方案,那是不是可以在每一個組件外面都包裹一層 React.memo 呢?

其實是不需要的,React.memo 由于自身需要做前后兩次 props 的淺層比較,是要消耗一定性能的。再者有 React diff 算法的加持下,其實很多DOM 元素并不會被真正的渲染,所以很多組件就算沒有做 memo 優(yōu)化,仍然不會對項目的性能造成什么影響。

所以我們在想使用 React.memo 之前最好先想想這個組件重新渲染和淺層比較 props 誰花費的性能較大再決定是否使用它,如果子組件本身比較復雜,那確實是可以在它外面套一層 memo 進行優(yōu)化的

到此,關于“Jira任務管理系統(tǒng)項目實例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI