# React Context
# 介绍
# 注意事项
在React的官网文档里面提到了一个一个注意事项 caveats (opens new window)
不建议通过如下的方式书写,会带来一些问题,那会有哪些问题呢?
class App extends React.Component {
render() {
return (
<Provider value={{something: 'something'}}>
<Toolbar />
</Provider>
);
}
}
举例来说
import React, { useState } from 'react';
// class Toolbar extends React.PureComponent {
class Toolbar extends React.Component {
shouldComponentUpdate(nextProps, nextState, nextContext) {
//shallow compare will failed here and cause a render.
if(this.props.value !== nextProps.value) {
return true
}
return false;
}
render() {
console.log('render Toolbar');
return (
<div>
I am Toolbar
</div>
)
}
}
// const ThemeContext = React.createContext('light');
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
value: { something: 'something' },
};
}
render() {
console.log('render Child');
return (
/*<Toolbar value={ {value: this.state.value} }/> use this line you will see see LOG: `render Toolbar`*/
<Toolbar value={ this.state.value }/>
);
}
}
function App() {
const [value, SetValue] = useState(0)
const onClick = () => {
SetValue(value + 1)
};
return (
<div>
<Child/>
<button onClick={ onClick }>{ value }</button>
</div>
);
}
export default App;
如果按照每次都是生成新的{}
那么通过shouldComponent(自己实现,仅简单比较Props,和或者PureComponent原理一样)或者PureComponent来进行比较时就会失败,造成不必要的一次渲染。
使用Context也是类似的
import React, { useState } from 'react';
// class Toolbar extends React.PureComponent {
class Toolbar extends React.Component {
shouldComponentUpdate(nextProps, nextState, nextContext) {
if(this.props.value !== nextProps.value) {
return true
}
return false;
}
render() {
console.log('render Toolbar');
return (
<div>
I am Toolbar
</div>
)
}
}
class Child extends React.PureComponent {
render() {
console.log('render Child');
return <ThemeContext.Consumer>
{ value => <Toolbar value={ value }/> }
</ThemeContext.Consumer>
}
}
class Parent extends React.Component {
constructor() {
super();
this.state = {
value: {
name: 'name'
}
}
}
render() {
return (
/*<ThemeContext.Provider value={ { name: 'name'} }>*/ // <== you will see LOG: `render Toolbar`
<ThemeContext.Provider value={ this.state.value }>
<Child/>
</ThemeContext.Provider>
)
}
}
const ThemeContext = React.createContext('');
function App() {
const [value, SetValue] = useState(0);
const onClick = () => {
SetValue(value + 1)
};
return (
<div>
<button onClick={ onClick }>{ value }</button>
<Parent/>
</div>
);
}
export default App;