ts对createContext进行封装使用

不说废话,直接上代码

随便写了一个reducer.ts

export interface StateProps {
  id: number;
  text: string;
  isFinished: boolean;
}

export interface ActionProps {
  type: string;
  [key: string]: any;
}

const reducer = (state: StateProps[], action: ActionProps) => {
  switch (action.type) {
    case "ADD":
      return [...state, action.todo];
    case "CHANGEFINISHED":
      return state.map((item) => {
        if (item.id === action.id) {
          return Object.assign({}, item, {
            isFinished: !item.isFinished,
          });
        }
        return item;
      });
    default:
      return state;
  }
};

export default reducer;

然后看封装的createContext.tsx文件

import React, { createContext, Dispatch } from "react";
import { StateProps, ActionProps } from "../store/reducer";
import _ from "lodash";

export interface ContextProps {
  value: {
    state: StateProps[];
    dispatch: Dispatch<ActionProps>;
  };
}

export const MyContext = createContext({} as ContextProps);

const MyProvide = (props: React.PropsWithChildren<ContextProps>) => {
  return (
    <MyContext.Provider value={_.omit(props, "children")}>
      {props.children}
    </MyContext.Provider>
  );
};
export default MyProvide;

如何使用这个createContext.tsx呢

import React, {
  useRef,
  FC,
  useReducer,
  Dispatch,
} from "react";
import ToDoInput from "./todo-input";
import MyProvide from "./createContext";
import reducer, { StateProps, ActionProps } from "../store/reducer";

interface ContextProps {
  state: StateProps[];
  dispatch: Dispatch<ActionProps>;
}

const ToDo: FC = () => {
  const initState: StateProps[] = [];
  const [state, dispatch] = useReducer(reducer, initState);
  const transferParameter: ContextProps = { state, dispatch }return (
    <>
      <MyProvide value={transferParameter}>
        <ToDoInput /> // 子组件
      </MyProvide>
    </>
  );
};
export default ToDo;

然后你在子组件可以获取到state和dispatch,并且通过dispatch发送事件

import React, { useContext, useEffect, useRef } from "react";
import { MyContext } from "./my-provide";

const ToDoInput = () => {
  const { value: { dispatch, state } } = useContext(MyContext);

  const inputRef = useRef<HTMLInputElement>(null);

  const addTodoHandle = () => {
    const value = inputRef.current!.value;
    dispatch({
      type: "ADD",
      todo: {
        id: new Date().getTime(),
        text: value,
        isFinished: false,
      },
    });
    inputRef.current!.value = '';
  };

  useEffect(() => {
    inputRef.current!.focus();
  }, [])
  return (
    <>
      <input
        type="text"
        placeholder="请输入"
        ref={inputRef}
      />
      <button onClick={addTodoHandle}>添加</button>
    </>
  );
};
export default ToDoInput;

子组件发送dispatch事件改变state之后,在父组件里面就能接收到,多层通信也是这样操作

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值