Skip to content

Latest commit

 

History

History
82 lines (63 loc) · 2.97 KB

45.精读《React's new Context API》.md

File metadata and controls

82 lines (63 loc) · 2.97 KB

45.精读《React's new Context API》.md

React-redux mobx-react react-router 去 Context API, 使用新 context API 作为支持

概述

  • Hooks 版新 API: useContext , useReducer

  • 新版 context API

    const ThemeContext = React.createContext('light')
    class ThemeProvider extends React.Component {
      state = {theme: 'light'}
    render() {
      return ThemeContext.provide(this.state.theme, this.props.children)
    }
    }
    const ThemeConsumer = ({children}) => ThemeContext.consume(children)
    
    class App extends React.Component {
      render() {
        <ThemeProvider>
          	<ThemeConsumer>{val => <div>{val}</div>}</ThemeConsumer>
          </ThemeProvider>
      }
    }
    • React.createContext 创建新的上下文并且赋值,返回对象包含providerconsumer
    • provide是一个容器,所有子元素都能通过consumer访问到这个 context 的值

精读

  • react17 会废除旧 context 这个 api,许多库需要升级,codemod 会自动升级
  • 解决问题
    • Context 多层嵌套问题
      • 构造聚合 Consumer 解决嵌套问题,或者通过react-context-composer第三方库解决
    • 绕过 shouldComponentUpdate
      • 使用 forceUpdate 绕过 shouldComponentUpdate,原因是全局状态管理工具接管了自己的组件更新时机,纵使保留组件原本的更新机制,当数据流发生变化时,需要绕过一切更新机制,直接触发目标组件的一整套渲染生命周期
    • 是否需要 redux
      • Redux: 利用 react 特性,利用全局数据流解决组件间数据通信的问题,没有 react-redux,redux 只剩下简单的 Action 和 Reducer
      • mobx:主打自动追踪变量引用,当变量被修改时自动刷新视图, 组件数据打通的同时对于自动绑定带来的效率提升是其中一大亮点
      • rxjs:核心竞争力在数据处理能力和数据源的抽象,做到了副作用隔离在数据处理流程之外
    • flux 多 store 思想再度崛起?
      • Context API 主打中心化 store 储存能力,不会在项目中创建多个 store 制造混乱

summary

  • 新 context API 不是银弹,不能解决业务组件和项目数据流绑定导致的耦合问题

  • 只要给组件注入数据,注入的节点一定依赖一个特性的项目环境或者变量

  • 数据流框架无法被取代,因为数据流框架的核心竞争力不在数据流的 DI(Dependency Inject) 上,而是对数据的处理

  • 此次引入 react 提供了一个稳定好用的依赖注入官方 api,处理国际化需要上下文的情景,使用实例:

    const Locale = React.createContext({
      text: 'menu'
    })
    class MyComponent extends React.Component {
      render() {
        <Locale.consume>
          	{text => (
             	<span>this is the {text}</span>
             )}
          </Locale.consume>
      }
    }
    class App extends React.Compoent {
      render() {
        <LocalProvider>
          	<MyComponnet />
          </LocalProvider>
      }
    }