只讲解新版本context,v16.3以后版本
类组件和函数组件只在consumer上有区别。
const ThemeContext = React.createContext(null) // 主题颜色Context
const theme = { //主题颜色
dark:{ color:'#1890ff' , background:'#1890ff', border: '1px solid blue' ,type:'dark', },
light: { color:'#fc4838' , background:'#fc4838', border: '1px solid pink' ,type:'light' }
}
class Input extends React.Component{
static contextType = ThemeContext
shouldComponentUpdate(){
return false
}
render(){
const { color,border } = this.context
const {label , placeholder } = this.props
return <div>
<label style={{ color }} >{ label }</label>
<input className="input" placeholder={placeholder} style={{ border }} />
</div>
}
}
function Checkbox (props){
const { label ,name, onChange } = props
const { type , color, setTheme } = React.useContext(ThemeContext)
return (
<div className="checkbox" onClick={()=> setTheme(theme[name])} >
<label htmlFor="name" > {label} </label>
<input type="checkbox" id={name} value={type} name={name} checked={ type === name } style={{ color } } />
</div>
)
}
const Box = memo(function(props) {
return <ThemeContext.Consumer>
{ themeContextValue => {
const { border,color } = themeContextValue
return <div className="context_box" style={{ border,color }} >
{ props.children }
</div>
} }
</ThemeContext.Consumer>
})
class App extends React.PureComponent {
static contextType = ThemeContext
render() {
const { border , setTheme ,color ,background} = this.context
return <div className="context_app" style={{ border , color }} >
<div className="context_change_theme" >
<span> 选择主题: </span>
<Checkbox label="light" name="light" onChange={ ()=> setTheme(theme.light) } />
<Checkbox label="dark" name="dark" onChange={ ()=> setTheme(theme.dark) } />
</div>
<div className='box_content' >
<Box>
<Input label="姓名:" placeholder="请输入姓名" />
<Input label="age:" placeholder="请输入年龄" />
<button className="searchbtn" style={ { background } } >确定</button>
<button className="concellbtn" style={ { color } } >取消</button>
</Box>
<Box >
<div className="person_des" style={{ color:'#fff' , background }} >
I am alien <br/>
let us learn React!
</div>
</Box>
</div>
</div>
}
}
export default function Text() {
const [ themeContextValue ,setThemeContext ] = React.useState(theme.dark)
return <ThemeContext.Provider value={ { ...themeContextValue, setTheme:setThemeContext } } >
<App/>
</ThemeContext.Provider>
}
Q: Provder 的 value 改变,会使所有消费 value 的组件重新渲染。如何优化
- 利用 memo,pureComponent 对子组件 props 进行浅比较处理
- 使用useMemo()对 React element 对象的缓存。React 每次执行 render 都会调用 createElement 形成新的 React element 对象,如果把 React element 缓存下来,下一次调和更新时候,就会跳过该 React element 对应 fiber 的更新。