使用createContext的正确姿态
本文介绍一下 React 中常见的 Context API
在class
和Hook
中的使用方式。在使用 Context API
之前,我们还需要知道为啥要使用❓
引入Context的原因
考虑到组件有可能 层层嵌套 ,在传 props 的过程中,如果书写大量的 ...props
,造成props
数据混乱。
如何使用context
- 首先要引入 React 内置的 React Context API 📦
- 然后创建
provider
- 最后创建
consumer
使用hook可以不用创建consumer
使用 createContext
// context.jsx
import React,{createContext,useState} from 'react'
export const demoContext = createContext({})
export const {Provider,Consumer } = demoContext;
const Context = () =>{
const [name,setName] = useState('Mr.long');
const handleNameClick = (params) => setName(params);
const initValue ={
name,
handleNameClick
}
return <Provider value={initValue}>{props.children}</Provider>
}
export default Context
使用 Consumer 组件
consumer
是从createContext
函数的返回值导出。它是个render props
模式组件。
// render Name 组件
import React from 'react'
export default Render class extends React.Component{
render(){
return <div>
<p>{props.name}</p>
<button onClick ={() => props.handleNameClick(props.name +'!')}>点击修改名</button>
</div>
}
}
// app.jsx
import {Context,Consumer} from './Context'
import React from 'react'
import RenderName from './renderName'
const App = () =>{
return <Context>
<Consumer>
{(value) =><RenderName {...value} />}
</Consumer>
</Context>
}
useContext
想在hook
中使用Context
可以借助useContext
来使用,来看代码。
import React,{useContext} from 'react'
import {demoContext} from './context'
const HookContext =() =>{
// useContext 传入的是createContext出来的实例 而不是他里面的组件
//这里的contextValue就能拿到值,不在需要Consumer 组件了
const contextValue = useContext(demoContext)
return (
<div>
{contextValue.name}
<button onClick={() => contextValue.handleNameClick(contextValue.name +'!')}>点击改变值</button>
</div>
);
}
export default HookContext
总结
使用Context
可以避免的组件的层层props
嵌套的问题。但是它使用consumer
拿值时,会多一层组件。但得益于useContext
hook我们可以不使用consumer
组件。直接拿到值,直观。一般的使用场景,如那拿全局的class前缀,或者国际化,Ui主题颜色等。
当 Provider 的 value
值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate
函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。