05. 使用useContext、useReducer实现类似Redux的全局变量效果

146 阅读1分钟
  • 文件目录

    └─components
      └─ShowArea.js    文本内容
      └─Buttons.js     按钮组件
      └─Color.js       createContext组件-让ShowArea和Buttons共享中泰
    └─Panel.js	   在这里合并三个组件
    └─index.js	   入口文件
    
    • 文件代码

      • components

        // ShowArea.js
        
        import React, {useContext} from 'react';
        
        // 引入context的名字
        import {ColorContext} from './Color';
        
        function ShowArea(){
          // 获取context的value值里面的color
          const {color} = useContext(ColorContext);
          return (
            <div> <p style={{color:color}}>这段文字的颜色是blue</p> </div>
          )
        }
        export default ShowArea;
        
        //-----------------------------------------------------------------
        
        //Buttons.js
        
        import React,{ useContext } from 'react';
        import { ColorContext,UPDATE_COLOR } from './Color';
        function Buttons(){
          // 获取共享出来的派发器(dispatch)
          const {dispatch} = useContext(ColorContext);
          
          return (
            <div>
              // 点击更新
              <button
                onClick={()=>{ 
                  dispatch({ type:UPDATE_COLOR, color:'red' })
                }}
              >红色</button>
              <button
                onClick={()=>{
                  dispatch({ type:UPDATE_COLOR, color:'yellow' })
                }}
              >黄色</button>
            </div>
          ) 
        }
        export default Buttons;
        
        //-----------------------------------------------------------------
        
        //Color.js
        
        import React, { createContext, useReducer } from 'react';
        
        // 导出context的名称,方便子组件使用
        export const ColorContext = createContext();
        
        // 更新时使用的type 创建成常量方便修改
        export const UPDATE_COLOR = 'UPDATE_COLOR';
        
        // reducer函数
        function Reducer(state,action){
          switch (action.type) {
            case UPDATE_COLOR:
              return action.color;      
            default:
              return state;
          }
        }
        
        export const Color = props => {
          // 获取color和dispatch
          // color默认是第二个参数 dispatch相当于一个派发器,修改时使用
          const [color,dispatch] = useReducer(Reducer,'blue'); 
         
          return (
            <div>
              //把color和dispatch共享出去,方便修改和获取
              <ColorContext.Provider value={{ color,dispatch }}>
                //默认值是蓝色
                {props.children}
              </ColorContext.Provider>
            </div>
          )
        }
        
      • Panel.js

        import React from 'react';
        import ShowArea from './components/ShowArea';
        import Buttons from './components/Buttons';
        import { Color } from './components/Color';
        //Color就是ColorContext.Provider
        function Panel() {
          return (
            <div>
              <Color>
        		//这两个子组件就是props.children        
                <ShowArea />
                <Buttons />
              </Color>
            </div>
          )
        }
        export default Panel;
        
      • index.js

        import React from 'react';
        import ReactDOM from 'react-dom';
        import Panel from './Panel';
        ReactDOM.render(<Panel />, document.getElementById('root'));