美文网首页
React+ts+hooks结合UerContext和useRe

React+ts+hooks结合UerContext和useRe

作者: Poppy11 | 来源:发表于2021-10-16 16:47 被阅读0次

    1、首先创建store文件,有reducer.ts和state.ts文件
    2、在state.ts中创建需要存储的数据以及类型

    export interface storyTableState {
      storyTableData: StoryTableData;
      jiraStoryList: Array<JiraStoryList>;
      tableLoading: boolean;
      showEditWorkLogModal: boolean;
      editWorkLogInfo: EditWorkLogInfo;
      showSearchDrawer: boolean;
    }
    
    export const initialStoryTableState: storyTableState = {
      storyTableData: { tableColumns: [], tableData: [] },
      jiraStoryList: [],
      tableLoading: true,
      showEditWorkLogModal: false,
      editWorkLogInfo: { userName: '', userID: 0, dateTime: '' },
      showSearchDrawer:false
    };
    

    3、在reducer.ts中创建action和context

    export type storyTableAction =
      | { type: 'UpdateState'; update: Partial<storyTableState> }
      | { type: 'SearchStoryTable'; request: SearchTableCondition; searchTableCondition: SearchTableCondition }
      | { type: 'SavePlan'; saveRequest: SavePlan; searchTableRequest: SearchTableCondition }
      | { type: 'InitDate'; initRequest: SearchTableCondition };
    
    export type Dispatcher = (action: storyTableAction) => any;
    export interface storyTableContext {
      state: storyTableState;
      dispatch: Dispatcher;
    }
    
    export const StoryTableContext = createContext<storyTableContext>({ state: initialStoryTableState, dispatch: value => {} });
    

    4、在reducer.ts中使用dispatch中间件,处理异步数据

    export function dispatchMiddleware(next: Dispatch<storyTableAction>): Dispatcher {
      return async (action: storyTableAction) => {
        switch (action.type) {
          case 'InitDate':
            next({ type: 'UpdateState', update: { tableLoading: true } });
            const initStoryResponse = await searchStoryAjax(action.initRequest);
            next({ type: 'UpdateState', update: { storyTableData: initStoryResponse, tableLoading: false } });
            const jiraStoryListResponse: Array<JiraStoryList> = await initJiraStoryListAjax();
            next({ type: 'UpdateState', update: { jiraStoryList: jiraStoryListResponse } });
            break;
          case 'SavePlan':
            console.log(action.searchTableRequest);
            await savePlanAjax(action.saveRequest);
            const saveSearchResponse = await searchStoryAjax(action.searchTableRequest);
            next({ type: 'UpdateState', update: { showEditWorkLogModal: false, storyTableData: saveSearchResponse } });
            break;
          case 'SearchStoryTable':
            next({ type: 'UpdateState', update: { tableLoading: true } });
            const searchStoryResponse = await searchStoryAjax(action.request);
            next({
              type: 'UpdateState',
              update: {
                tableLoading: false,
                storyTableData: searchStoryResponse,
                searchTableCondition: action.searchTableCondition,
                showSearchDrawer: false,
              },
            });
            break;
          default:
            next(action);
        }
      };
    }
    

    5、在reducer.ts中使用真正reduce

    export const storyTablereducer = (state: storyTableState, action: storyTableAction) => {
      switch (action.type) {
        case 'UpdateState':
          return { ...state, ...action.update };
        default:
          return state;
      }
    };
    

    6、在根组件中使用Reducer,并且使用Context共享数据给所有子组件

    export default function StoryTableView() {
      const [state, dispatch] = useReducer(storyTablereducer, initialStoryTableState);
      const middleDispatch = dispatchMiddleware(dispatch);
      const { searchTableCondition } = state;
      const { timeRange, projectName } = searchTableCondition;
      useEffect(() => {
        initData();
      }, []);
    
      const initData = async () => {
        middleDispatch({ type: 'InitDate', initRequest: { timeRange, projectName } });
      };
      return (
        <StoryTableContext.Provider value={{ state, dispatch: dispatchMiddleware(dispatch) }}>
          <StoryTableHeader />
          <div className="story-table-view">
            <StoryTable />
          </div>
          <SearchDrawwer/>
        </StoryTableContext.Provider>
      );
    }
    
    

    7、子组件中使用context获取reducer中的state

     const { state, dispatch } = useContext(StoryTableContext);
      const { jiraStoryList, searchTableCondition, showSearchDrawer } = state;
    

    相关文章

      网友评论

          本文标题:React+ts+hooks结合UerContext和useRe

          本文链接:https://www.haomeiwen.com/subject/pdyboltx.html