react数据处理
- innerState和Context处理数据状态;
- React hooks消费全局数据状态;
- ReCompose的widthStateHandlers中心化管理全局数据状态;
innerState
setState后的及时处理数据方案
传入处理后的数据
- 传入处理后的组件
二、原理
- 订阅广播
eventEmitter订阅广播
function eventEmiter(value){
let handlers = [];
return {
on(handler){
handlers.push(handler)
},
off(handler){
handlers.filter(h=>h !== handler)
},
get(){return value},
set(newVal,changeBits){
value = newVal;
handlers.foreach(h=>h(value,changeBits))
},
}
}
objectIs
function(x,y){
if(x === y){
// 0 === -0 => true
// Infinity === -Infinity =>false
return x !== 0 || 1/x === 1/y
}else{
// NaN === NaN => false
return x !== x && y !== y
}
}
API
1、创建Context对象
React.createContext(defaultValue)
- 返回context对象{Provider,Consumer}
- 订阅了context的子组件,子组件会从最近的Provider读取Context
- 没有匹配到Provider时候,才会生效defaultValue,undefined传参不会生效defaultValue
function createReactContext(){
class Provider extends React.Component{};
class Consumer extends React.Component{};
return {
Provider,
Consumer
}
}
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)){
} } } render(){ return this.props.children } }this.eventEmitter.set(newVal)
- 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)
} }
- 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