参考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几个步骤
- 创建上下文对象,导出一个对象,该对象又导出俩组件
// createContext() 接收一个参数,作为默认状态值
const Context = React.createContext(null);
// 提供俩组件
let { Provider, Consumer } = Context;
- 使用上下文对象导出的组件
Provider
: 提供者,默认顶级父组件, 有一个默认写死的属性value
,并且只能通过value
属性向下传值Consumer
: 消费者, 用于子组件从父组件取值
- 父组件, 提供数据,供子组件消费
// ... 略
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>
);
}
}
- 子组件获取父组件向下传的的数据,
class AChild extends Component {
render() {
return (
<Consumer>
{(value) => (
<div style={{ border: '3px solid #400', margin: 5 }}>
<p>我是(类组件)子组件A</p>
<span>我接收的值:{value}</span>
</div>
)}
</Consumer>
);
}
}
- 类组件还可以使用
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>
);
}
}
- 函数组件只能使用
Consumer
获取数据
function BChild() {
return (
<Consumer>
{(value) => {
return (
<div style={{ border: '2px solid #f90', margin: 5 }}>
<p>我是(函数组件)子组件B</p>
<span>我接收的值:{value}</span>
</div>
);
}}
</Consumer>
);
}