在之前 react 的工程项目中, 关于数据流动以及父子组件中数据通信大都是通过 react-reduxredux 来完成, 虽然可以解决问题, 但是这种数据管理是较为复杂的, 在最新的 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
参考文章
React's new Context API
从新的 Context API 看 React 应用设计模式
来源: https://juejin.im/post/5a911bc7f265da4e9016c6ea