中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

倉庫進(jìn)銷存管理軟件免費(fèi)版搜索引擎優(yōu)化分析

倉庫進(jìn)銷存管理軟件免費(fèi)版,搜索引擎優(yōu)化分析,西安市做網(wǎng)站,12306網(wǎng)站是哪家公司做開發(fā)的文章目錄 一、項(xiàng)目起航:項(xiàng)目初始化與配置二、React 與 Hook 應(yīng)用:實(shí)現(xiàn)項(xiàng)目列表三、TS 應(yīng)用:JS神助攻 - 強(qiáng)類型四、JWT、用戶認(rèn)證與異步請求五、CSS 其實(shí)很簡單 - 用 CSS-in-JS 添加樣式六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理七、Hook&…

文章目錄

    • 一、項(xiàng)目起航:項(xiàng)目初始化與配置
    • 二、React 與 Hook 應(yīng)用:實(shí)現(xiàn)項(xiàng)目列表
    • 三、TS 應(yīng)用:JS神助攻 - 強(qiáng)類型
    • 四、JWT、用戶認(rèn)證與異步請求
    • 五、CSS 其實(shí)很簡單 - 用 CSS-in-JS 添加樣式
    • 六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理
    • 七、Hook,路由,與 URL 狀態(tài)管理
    • 八、用戶選擇器與項(xiàng)目編輯功能
    • 九、深入React 狀態(tài)管理與Redux機(jī)制
      • 1&2
      • 3&4
      • 5~8
      • 9&10
      • 11.用redux-thunk管理登錄狀態(tài)


學(xué)習(xí)內(nèi)容來源:React + React Hook + TS 最佳實(shí)踐-慕課網(wǎng)


相對原教程,我在學(xué)習(xí)開始時(shí)(2023.03)采用的是當(dāng)前最新版本:

項(xiàng)版本
react & react-dom^18.2.0
react-router & react-router-dom^6.11.2
antd^4.24.8
@commitlint/cli & @commitlint/config-conventional^17.4.4
eslint-config-prettier^8.6.0
husky^8.0.3
lint-staged^13.1.2
prettier2.8.4
json-server0.17.2
craco-less^2.0.0
@craco/craco^7.1.0
qs^6.11.0
dayjs^1.11.7
react-helmet^6.1.0
@types/react-helmet^6.1.6
react-query^6.1.0
@welldone-software/why-did-you-render^7.0.1
@emotion/react & @emotion/styled^11.10.6

具體配置、操作和內(nèi)容會有差異,“坑”也會有所不同。。。


一、項(xiàng)目起航:項(xiàng)目初始化與配置

  • 一、項(xiàng)目起航:項(xiàng)目初始化與配置

二、React 與 Hook 應(yīng)用:實(shí)現(xiàn)項(xiàng)目列表

  • 二、React 與 Hook 應(yīng)用:實(shí)現(xiàn)項(xiàng)目列表

三、TS 應(yīng)用:JS神助攻 - 強(qiáng)類型

  • 三、 TS 應(yīng)用:JS神助攻 - 強(qiáng)類型

四、JWT、用戶認(rèn)證與異步請求

  • 四、 JWT、用戶認(rèn)證與異步請求(上)

  • 四、 JWT、用戶認(rèn)證與異步請求(下)

五、CSS 其實(shí)很簡單 - 用 CSS-in-JS 添加樣式

  • 五、CSS 其實(shí)很簡單 - 用 CSS-in-JS 添加樣式(上)

  • 五、CSS 其實(shí)很簡單 - 用 CSS-in-JS 添加樣式(下)

六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理

  • 六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理(上)

  • 六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理(中)

  • 六、用戶體驗(yàn)優(yōu)化 - 加載中和錯(cuò)誤狀態(tài)處理(下)

七、Hook,路由,與 URL 狀態(tài)管理

  • 七、Hook,路由,與 URL 狀態(tài)管理(上)

  • 七、Hook,路由,與 URL 狀態(tài)管理(中)

  • 七、Hook,路由,與 URL 狀態(tài)管理(下)

八、用戶選擇器與項(xiàng)目編輯功能

  • 八、用戶選擇器與項(xiàng)目編輯功能(上)

  • 八、用戶選擇器與項(xiàng)目編輯功能(下)

九、深入React 狀態(tài)管理與Redux機(jī)制

1&2

  • 九、深入React 狀態(tài)管理與Redux機(jī)制(一)

3&4

  • 九、深入React 狀態(tài)管理與Redux機(jī)制(二)

5~8

  • 九、深入React 狀態(tài)管理與Redux機(jī)制(三)

9&10

  • 九、深入React 狀態(tài)管理與Redux機(jī)制(四)

11.用redux-thunk管理登錄狀態(tài)

既然模態(tài)框使用 redux 來管理了,而 reduxcontext 是競爭關(guān)系,那可以嘗試將之前管理登錄狀態(tài)的 context 改為 redux

新建 src\store\auth.slice.ts

import { User } from "screens/ProjectList/components/SearchPanel";
import { createSlice } from "@reduxjs/toolkit";
import * as auth from 'auth-provider'
import { AuthForm, initUser as _initUser } from "context/auth-context";
import { AppDispatch, RootState } from "store";interface State {user: User | null
}const initialState: State = {user: null
}export const authSlice = createSlice({name: 'auth',initialState,reducers: {setUser(state, action) {state.user = action.payload}}
})const { setUser } = authSlice.actionsexport const selectUser = (state: RootState) => state.auth.userexport const login = (form: AuthForm) => (dispatch: AppDispatch) => auth.login(form).then(user => dispatch(setUser(user)))
export const register = (form: AuthForm) => (dispatch: AppDispatch) => auth.register(form).then(user => dispatch(setUser(user)))
export const logout = () => (dispatch: AppDispatch) => auth.logout().then(() => dispatch(setUser(null)))
export const initUser = () => (dispatch: AppDispatch) => _initUser().then(user => dispatch(setUser(user)))

需要提前將 src\context\auth-context.tsx 中的 interface AuthForminitUser(視頻中對應(yīng)bootstrapUser) 導(dǎo)出

最后在 src\store\index.ts 中統(tǒng)一注冊:

...
import { authSlice } from "./auth.slice";// 集中狀態(tài)注冊
export const rootReducer = {projectList: projectListSlice.reducer,auth: authSlice.reducer
};
...

接下來使用 redux 中的 auth 相關(guān)功能替換原有 context 提供的 auth 的功能

重構(gòu)需要找代碼上游中集中的一個(gè)點(diǎn):useAuth

修改 src\context\auth-context.tsx

+ import { ReactNode, useCallback } from "react";
...
+ import * as authStore from 'store/auth.slice'
+ import { useDispatch, useSelector } from "react-redux";
+ import { AppDispatch } from "store";- interface AuthForm {
+ export interface AuthForm {username: string;password: string;
}- const initUser = async () => {
+ export const initUser = async () => {let user = null;const token = auth.getToken();if (token) {// 由于要自定義 token ,這里使用 http 而非 useHttpconst data = await http("me", { token });user = data.user;}return user
};- const AuthContext = React.createContext<
-   | {
-       user: User | null;
-       login: (form: AuthForm) => Promise<void>;
-       register: (form: AuthForm) => Promise<void>;
-       logout: () => Promise<void>;
-     }
-   | undefined
- >(undefined);- AuthContext.displayName = "AuthContext";export const AuthProvider = ({ children }: { children: ReactNode }) => {// 這里要考慮到初始值的類型與后續(xù)值類型,取并組成一個(gè)泛型const {
-     data: user,error,isLoading,isReady,isError,run,
-     setData: setUser,} = useAsync<User | null>();
+   // const dispatch: (...args: unknown[]) => Promise<User> = useDispatch()
+   // const dispatch: AppDispatch = useDispatch()
+ 
+   // 這種寫法雖然消除了代碼中的報(bào)錯(cuò),但是控制臺會有報(bào)錯(cuò)
+   // useMount(async () => run(dispatch(await initUser())));
+   // useMount(() => run(dispatch(initUser())));
+   // 還原后登錄保持功能已經(jīng)是不好使的了useMount(() => run(initUser()));-   const login = (form: AuthForm) => auth.login(form).then(setUser);
-   const register = (form: AuthForm) => auth.register(form).then(setUser);
-   const logout = () => auth.logout().then(() => setUser(null));if (isReady || isLoading) {return <FullPageLoading />;}if (isError) {return <FullPageErrorFallback error={error} />;}-   return (
-     <AuthContext.Provider
-       children={children}
-       value={{ user, login, register, logout }}
-     />
-   );
+   return <div>
+     { children }
+   </div>
};export const useAuth = () => {
-   const context = React.useContext(AuthContext);
-   if (!context) {
-     throw new Error("useAuth 必須在 AuthProvider 中使用");
-   }
-   return context;
+   // 這種寫法有報(bào)錯(cuò)
+   // const dispatch: (...args: unknown[]) => Promise<User> = useDispatch()
+   const dispatch: AppDispatch = useDispatch()
+   const user = useSelector(authStore.selectUser)
+   const login = useCallback((form: AuthForm) => dispatch(authStore.login(form)), [dispatch])
+   const register = useCallback((form: AuthForm) => dispatch(authStore.register(form)), [dispatch])
+   const logout = useCallback(() => dispatch(authStore.logout()), [dispatch])
+   // const login = useCallback((form: AuthForm) => authStore.login(form), [])
+   // const register = useCallback((form: AuthForm) => authStore.register(form), [])
+   // const logout = useCallback(() => authStore.logout(), [])
+   // login({ username: '123', password: '123' }).then()
+   return { user, login, register, logout };
};

這種寫法會報(bào)錯(cuò) const dispatch: (...args: unknown[]) => Promise<User> = useDispatch()

不能將類型“Dispatch<AnyAction>”分配給類型“(...args: unknown[]) => Promise<User>”。參數(shù)“action”和“args” 的類型不兼容。不能將類型“unknown”分配給類型“AnyAction”

替換為 const dispatch: AppDispatch = useDispatch() 后正常

useMount(async () => run(dispatch(await initUser()))) 中不加 async..await 的話會有如下報(bào)錯(cuò)提示:

沒有與此調(diào)用匹配的重載。第 1 個(gè)重載(共 3 個(gè)),“(thunkAction: ThunkAction<Promise<User | null>, { projectList: State; auth: State; }, undefined, AnyAction>): Promise<User | null>”,出現(xiàn)以下錯(cuò)誤。類型“Promise<any>”的參數(shù)不能賦給類型“ThunkAction<Promise<User | null>, { projectList: State; auth: State; }, undefined, AnyAction>”的參數(shù)。類型“Promise<any>”提供的內(nèi)容與簽名“(dispatch: ThunkDispatch<{ projectList: State; auth: State; }, undefined, AnyAction>, getState: () => { projectList: State; auth: State; }, extraArgument: undefined): Promise<...>”不匹配。第 2 個(gè)重載(共 3 個(gè)),“(action: AnyAction): AnyAction”,出現(xiàn)以下錯(cuò)誤。類型“Promise<any>”的參數(shù)不能賦給類型“AnyAction”的參數(shù)。類型 "Promise<any>" 中缺少屬性 "type",但類型 "AnyAction" 中需要該屬性。第 3 個(gè)重載(共 3 個(gè)),“(action: AnyAction | ThunkAction<Promise<User | null>, { projectList: State; auth: State; }, undefined, AnyAction>): AnyAction | Promise<...>”,出現(xiàn)以下錯(cuò)誤。類型“Promise<any>”的參數(shù)不能賦給類型“AnyAction | ThunkAction<Promise<User | null>, { projectList: State; auth: State; }, undefined, AnyAction>”的參數(shù)。不能將類型“Promise<any>”分配給類型“AnyAction”。ts(2769)
auth-context.tsx(41, 31): 是否忘記使用 "await"?
index.d.ts(19, 3): 在此處聲明了 "type"。
auth-context.tsx(41, 31): 是否忘記使用 "await"?
auth-context.tsx(41, 31): 是否忘記使用 "await"?

最終運(yùn)行結(jié)果:登錄,注冊,登出功能都正常,只有登錄保持不正常


部分引用筆記還在草稿階段,敬請期待。。。

http://m.risenshineclean.com/news/60877.html

相關(guān)文章:

  • 做英文網(wǎng)站哪家好十堰seo優(yōu)化方法
  • 大學(xué)生兼職網(wǎng)網(wǎng)站建設(shè)計(jì)劃書海外黃岡網(wǎng)站推廣
  • 制作網(wǎng)站怎么做的網(wǎng)站優(yōu)化技巧
  • 西安制作網(wǎng)站的公司有福州seo排名優(yōu)化公司
  • 品牌型網(wǎng)站制作龍崗百度快速排名
  • 公司網(wǎng)站建設(shè)中心杭州網(wǎng)站優(yōu)化公司哪家好
  • 學(xué)校網(wǎng)站建設(shè)先進(jìn)事跡百度站長平臺提交網(wǎng)站
  • 網(wǎng)站聯(lián)系我們怎么做口碑營銷的作用
  • 采購網(wǎng)站平臺全國疫情今天最新消息
  • 祁東網(wǎng)站設(shè)計(jì)公司網(wǎng)站統(tǒng)計(jì)工具有哪些
  • 湖南湘潭網(wǎng)站建設(shè)第一推廣網(wǎng)
  • 一個(gè)做智能化的網(wǎng)站有哪些潮州網(wǎng)站建設(shè)
  • 網(wǎng)站怎么做二級域名網(wǎng)站友情鏈接的作用
  • 網(wǎng)站建設(shè)與開發(fā)的收獲與體會信息流優(yōu)化
  • 搜索李曉峰女生做sem還是seo
  • 簡約大氣網(wǎng)站設(shè)計(jì)欣賞愛站seo綜合查詢
  • 企業(yè)門戶網(wǎng)站布局特征軟件推廣平臺
  • 手機(jī)企業(yè)網(wǎng)站推廣網(wǎng)絡(luò)廣告的計(jì)費(fèi)方式
  • 宜昌網(wǎng)頁設(shè)計(jì)便宜的seo網(wǎng)絡(luò)營銷推廣
  • 電子政務(wù)政府網(wǎng)站建設(shè)方案云客網(wǎng)平臺
  • 沒簽合同網(wǎng)站做不好百度極簡網(wǎng)址
  • 購物網(wǎng)站平臺建設(shè)自己做網(wǎng)站
  • 自己怎么建立自己的國際網(wǎng)站晉城今日頭條新聞
  • 網(wǎng)站域名com和cn百度識圖網(wǎng)頁版
  • 帝國cms做中英文網(wǎng)站電商網(wǎng)站建設(shè)哪家好
  • 地方門戶網(wǎng)站建設(shè)要求福州百度分公司
  • wordpress附件插件南寧seo推廣優(yōu)化
  • 建設(shè)企業(yè)資質(zhì)雙網(wǎng)是哪兩個(gè)網(wǎng)站線上推廣平臺都有哪些
  • 福州正規(guī)網(wǎng)站建設(shè)公司報(bào)價(jià)軟文廣告案例分析
  • 酒店網(wǎng)站設(shè)計(jì)模板免費(fèi)創(chuàng)建網(wǎng)站的平臺