Context
提供了一个局部的全局作用域,使用Context则无需再手动的逐层传递props
。
当 Provider 的 value 值发生变化时,它内部包裹的所有消费组件都会重新渲染。
Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。
组件式
React.createContext
提供的Provider
和Consumer
React.createContext()
创建状态上下文
import React from "react"; const ActiveKey = React.createContext(); export default ActiveKey;
Consumer
组件来订阅Context
的变更,需要一个函数作为子元素,函数的第一个形参便是Provider
组件提供的value
值
<ActiveKey.Consumer> {activeKey => ( <div className={`bxer-content ${ activeKey === item.id ? "bxer-active" : "" }`} data-id={item.id} > <span className="bxer-label"></span> {item.text} </div> )} </ActiveKey.Consumer>
- Provider组件接收一个value属性,定义需要向所包裹的组件传递的值
<ActiveKey.Provider value={activeKey}> <div onClick={event => { setActiveKey(event.target.dataset.id, true); }} className="bxer-box" style={{ width: "200px" }} > {view} </div> </ActiveKey.Provider>
完整的示例如下:
import React from "react"; import ReactDOM from "react-dom"; // Create a Context const NumberContext = React.createContext(); // It returns an object with 2 values: // { Provider, Consumer } function App() { // Use the Provider to make a value available to all // children and grandchildren return ( <NumberContext.Provider value={42}> <div> <Display /> </div> </NumberContext.Provider> ); } function Display() { // Use the Consumer to grab the value from context // Notice this component didn't get any props! return ( <NumberContext.Consumer> {value => <div>The answer is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));
函数式
使用useContext
,接受React.createContext
的所有返回,也就是{ Provider, Consumer }
, 返回由provide组件传递过来的数值
// import useContext (or we could write React.useContext) import React, { useContext } from 'react'; // ... function Display() { const value = useContext(NumberContext); return <div>The answer is {value}.</div>; }