在之前react的工程项目中,关于数据流动以及父子组件中数据通信大都是通过react-redux、redux来完成,虽然可以解决问题,但是这种数据管理是较为复杂的,在最新的react16.3中推出了Context API,降低了开发的复杂度。
下面通过代码来进行详细的分析
首先创建一个context
的实例
import React from 'react';
import { render } from "react-dom";
const GlobalContext = React.createContext('dark');
生成的context
对象具有两个组件类对象
{
Provider: React.ComponentType<{value: T}>,
Consumer: React.ComponentType<{children: (value: T)=> React.ReactNode}>
}
接下来创建Provider
对象,该对象类似react-redux
中的Provide
对象
class GlobalContextProvider extends React.Component {
// 类似redux中的初始化状态
state = {
theme: 'dark'
};
// 类似reducer
handleContextChange = action => {
switch (action.type) {
case "UPDATE_THEME":
return this.setState({
theme: action.theme
});
default:
return;
}
};
render() {
return (
<GlobalContext.Provider
value={{
dispatch: this.handleContextChange,
theme: this.state.theme
}}
>
{this.props.children}
</GlobalContext.Provider>
);
}
}
接下来定义一个组件来改变state
const SubComponent = props => (
<div>
{/* 类似action,触发后改变状态 */}
<button
onClick={() =>
props.dispatch({
type: "UPDATE_THEME",
theme: "light"
})
}
>
change theme
</button>
<div>{props.theme}</div>
</div>
);
最后利用到上述提到的Consumer
对象加载状态并挂载到dom节点上
class App extends React.Component {
render() {
return (
<GlobalContextProvider>
<GlobalContext.Consumer>
{context => (
<SubComponent
theme={context.theme}
dispatch={context.dispatch}
/>
)}
</GlobalContext.Consumer>
</GlobalContextProvider>
);
}
}
render(<App />, document.getElementById("root"));
那么是不是就是可以利用新的API来代替redux呢?答案当然是否定的
我们可以看到上述的使用Context的方式与redux很类似,因此如果很复杂的应用这样的写法无异于使代码复杂混乱,因此可以这样进行选择:
- 注入式的组件,类似背景、语言这种控制全局的变量,可以选择这种
- 对于那些复杂的数据交互,父子组件通信还是选择redux
参考文章