react数据处理

  • innerState和Context处理数据状态;
  • React hooks消费全局数据状态;
  • ReCompose的widthStateHandlers中心化管理全局数据状态;

innerState

  • setState后的及时处理数据方案

    • setState({},callback)
    • params传递
    • hook的useRef

      Context

      一、使用场景:很多不同层级之间传递数据,数据发生改变,同时更新订阅组件;
      注意:只是为了解决多层次的嵌套使用组件组合,更好的控制反转组件;
  • 传入处理后的数据

  • 传入处理后的组件

二、原理

  • 订阅广播

eventEmitter订阅广播

  1. function eventEmiter(value){
  2. let handlers = [];
  3. return {
  4. on(handler){
  5. handlers.push(handler)
  6. },
  7. off(handler){
  8. handlers.filter(h=>h !== handler)
  9. },
  10. get(){return value},
  11. set(newVal,changeBits){
  12. value = newVal;
  13. handlers.foreach(h=>h(value,changeBits))
  14. },
  15. }
  16. }

objectIs

  1. function(x,y){
  2. if(x === y){
  3. // 0 === -0 => true
  4. // Infinity === -Infinity =>false
  5. return x !== 0 || 1/x === 1/y
  6. }else{
  7. // NaN === NaN => false
  8. return x !== x && y !== y
  9. }
  10. }

API

1、创建Context对象

  • React.createContext(defaultValue)

    • 返回context对象{Provider,Consumer}
    • 订阅了context的子组件,子组件会从最近的Provider读取Context
    • 没有匹配到Provider时候,才会生效defaultValue,undefined传参不会生效defaultValue
      1. function createReactContext(){
      2. class Provider extends React.Component{};
      3. class Consumer extends React.Component{};
      4. return {
      5. Provider,
      6. Consumer
      7. }
      8. }
  • Provider,允许消费订阅context的变化

    • Provider的value变化时,内部所有消费组件都会重新渲染
    • Provider和consumer组件不受shouldComponentUpdate影响,consumer组件在祖先组件退出更新的情况下,也能更新;
    • Object.is()判断新旧值的变化 ```javascript class Provider extends React.Component{ eventEmitter = eventEmiter(this.props.value); componentWillReceiveProps(nextProps){ if(this.props.value !== nextPorps.value ){ let oldVal = this.props.value,newVal = nextProps.value; if(!objectIs(oldVal,newVal)){
      1. this.eventEmitter.set(newVal)
      } } } render(){ return this.props.children } }


- contextType【未查看源码】
   - component.contextType = myContext
   - class 内部可以通过this.context在任意时间区间,访问value

```javascript
class my extends react.Component{
    render(){
      let value = this.context
  }
}
my.contextType = myContext
  • Consumer,消费组件

    • 函数作为子元素(function as a child),接收contextValue,返回React节点;
    • 最近的Provider提供的value,没有的话,展示defaultValue ```javascript class Comsumer extends React.Component{ state = { value:this.getValue() } componentWillReceiveProps(nextProps){

    } componentDidMount(){

    this.context.on(this.onUpdate)
    

    } componentWillUnmount(){

      this.context.off(this.onUpdate)
    

    } getValue(){

    return this.context.get()
    

    } onUpdate(){

    this.setState({xxx:yyy})
    

    } render(){ const child = Array.isArray(this.props.children) ? this.props.children[0] : this.props.children

    return child(this.state.value)
    

    } }

{ value=> / 基于context渲染 / }


- displayName
   - MyContext.displayName = 'bricks'


<a name="0780s"></a>
#### commonjsGlobal
```javascript
const commonjsGlobal: any =
    typeof globalThis !== 'undefined' // 'global proper'
    ? globalThis
    : typeof window !== 'undefined' 
        ? window // Browser
        : typeof global !== 'undefined'
            ? global // node.js
            : {}


function getUniqueId() {
    const key = '__global_unique_id__';
    return commonjsGlobal[key] = (commonjsGlobal[key] || 0) + 1;
}

资源

Context
https://github.com/StringEpsilon/mini-create-react-context/blob/master/src/implementation.ts
JavaScript 事件
https://www.cnblogs.com/goloving/p/9375079.html
额外资源:
https://www.robinwieruch.de/javascript-fundamentals-react-requirements