美文网首页
useReducer+useContext instead Re

useReducer+useContext instead Re

作者: 一土二月鸟 | 来源:发表于2020-08-13 07:36 被阅读0次
    • 遗留问题: 目前只实现了触发useContext通过父级组件同步子组件,未实现同级组件之间的state同步
    • reducer 根据不同的action返回不同的值
    export const SINGLE = 'single';
    export const DOUBLE = 'double';
    export const TRIPLE = 'triple';
    
    const numberReducer = (state, action) => {
    
      action.number = action.number ? action.number : 1;
    
      switch(action.type) {
        case SINGLE:
          return {
            ...state,
            number: state.number + 1
          }
        case DOUBLE:
          return {
            ...state,
            number: state.number + 2
          }
        case TRIPLE:
          return {
            ...state,
            number: state.number + 3
          }
        default:
          return {
            ...state
          }
      }
    }
    
    export default numberReducer;
    
    • context:通过useReducer获取到对应的dispatch,将dispatch及state传递给context.provider的value,方便共享context的组件调用reducer的dispatch
    import React, { useReducer } from 'react';
    import numberReducer from './numberReducer';
    
    export const NumberContext = React.createContext();
    
    const NumberProvider = (props) => {
    
      const [state, dispatch] = useReducer(numberReducer, {number: 1});
    
      return <>
        <NumberContext.Provider value={{state, dispatch}}>
          {props.children}
        </NumberContext.Provider>
      </>
    
    }
    
    export default NumberProvider;
    
    • index页面 通过provider将需要共享context的组件进行包裹
    import React from 'react';
    import ReactDOM from 'react-dom';
    import Button from './Button';
    import TextArea from './TextArea';
    import NumberProvider from './NumberProvider';
    import { SINGLE, DOUBLE, TRIPLE } from './numberReducer';
    
    const App = () => {
    
      return (
        <>
          <NumberProvider>
            <TextArea />
            <Button type={SINGLE} />
            <Button type={DOUBLE} />
            <Button type={TRIPLE} />
          </NumberProvider>
        </>
      );
    
    };
    
    ReactDOM.render(<App />, document.getElementById('root'));
    
    • 文字组件,负责从context获取相应的数据
    import React, { useContext } from 'react';
    import { NumberContext } from './NumberProvider';
    
    const TextArea = () => {
    
      const numberContext = useContext(NumberContext);
      console.log(numberContext)
    
    return <p>number is { numberContext.state.number }</p>
    }
    
    export default TextArea;
    
    • button组件 通过context调用reducer里的dispatch
    import React from 'react';
    import { useContext } from 'react';
    import { NumberContext } from './NumberProvider';
    import { TRIPLE, DOUBLE, SINGLE } from './numberReducer';
    
    const Button = ({ type }) => {
    
      const {dispatch} = useContext(NumberContext);
    
      const onClickBtn = () => {
        switch (type) {
          case SINGLE:
            dispatch({ type: SINGLE, number: 1 });
            return;
          case DOUBLE:
            dispatch({ type: DOUBLE, number: 2 });
            return;
          case TRIPLE:
            dispatch({ type: TRIPLE, number: 3 });
            return;
          default:
            dispatch({ type: SINGLE, number: 1 });
            return;
        }
      }
    
      const getBtnComp = () => {
        switch (type) {
          case SINGLE:
            return 'single increase';
          case DOUBLE:
            return 'double increase';
          case TRIPLE:
            return 'triple increase';
          default:
            return 'single increase';
        }
      }
    
      return <>
        <button style={stylesheet} onClick={onClickBtn}>
          {getBtnComp()}
        </button>
      </>
    }
    
    const stylesheet = {
      marginRight: '10px'
    }
    
    export default Button;
    

    相关文章

      网友评论

          本文标题:useReducer+useContext instead Re

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