redux5 - 实现 react-redux 前置技能之 react库的context的使用

参考redux仓库的src目录,初步手写实现了以下3个方法


  • createStore() : 创建数据仓库,导出了3个方法(dispacth,subscribe,getState)
  • combineReducers():合并多个小的reducer,传入一个对象
  • bindActionCreators() : 简化代码 api,把所有的action存入一个对象,和dispacth,一块传入此方法中 就不用再到处手动调用 dispatch

还剩下几个,先不说了,然而,就这么几行代码,已经基本让项目配合这些代码跑起来一个数据仓库了,然而,它还是有很多的冗余代码,比如在 react 项目中,还是需要每个文件 引入好多额外的redux 的东西, 所以,开发中还会结合 react-redux 一块使用,这样就只操作 props 了, 也是开发者比较熟悉的 react 的语法,关于 react-redux 的实现,参考仓库源码,发现,它就是使用了 react 的 context 这个api,实现的自上而下的跨组件通信

参考文档context一节

使用context几个步骤

  1. 创建上下文对象,导出一个对象,该对象又导出俩组件
// createContext() 接收一个参数,作为默认状态值
const Context = React.createContext(null);
// 提供俩组件
let { Provider, Consumer } = Context;
  1. 使用上下文对象导出的组件
  • Provider: 提供者,默认顶级父组件, 有一个默认写死的属性 value,并且只能通过value属性向下传值
  • Consumer: 消费者, 用于子组件从父组件取值

代码效果演示

  1. 父组件, 提供数据,供子组件消费
// ... 略
class App extends Component {
  render() {
    let value = 'hello';
    return (
      <Provider value={value}>
        <div style={{ border: '2px solid #950', padding: 5 }}>
          <p>我是父组件的默认值:{value}</p>
          <AChild />
          <CChild />
          <BChild />
        </div>
      </Provider>
    );
  }
}
  1. 子组件获取父组件向下传的的数据,
class AChild extends Component {
  render() {
    return (
      <Consumer>
        {(value) => (
          <div style={{ border: '3px solid #400', margin: 5 }}>
            <p>我是(类组件)子组件A</p>
            <span>我接收的值:{value}</span>
          </div>
        )}
      </Consumer>
    );
  }
}
  1. 类组件还可以使用this.context()语法获取
// 子组件3(类组件)
class CChild extends Component {
  static contextType = Context;
  render() {
    return (
      <div style={{ border: '2px solid #200', margin: 5 }}>
        <p>我是(类组件)子组件C</p>
        <span>我接收的值:{this.context}</span>
      </div>
    );
  }
}
  1. 函数组件只能使用Consumer获取数据
function BChild() {
  return (
    <Consumer>
      {(value) => {
        return (
          <div style={{ border: '2px solid #f90', margin: 5 }}>
            <p>我是(函数组件)子组件B</p>
            <span>我接收的值:{value}</span>
          </div>
        );
      }}
    </Consumer>
  );
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章