本文介绍一下 React 中常见的 Context API 的使用方式。在使用 Context API 以前,咱们还须要知道为啥要使用。❓react
考虑到组件有可能 层层嵌套 ,在传 props 的过程当中,若是书写大量的 ...props
或 propName={this.props.propValue}
会致使代码灰常丑陋 🤢:api
一层一层下来就像这样:markdown
<App>
<Switcher toggleState={this.state.toggle}>
<Pannel toggleState={props.toggleState}>
<div onClick={handleClick}>{props.toggleState ? '✔' : '❌'}
复制代码
因此引入 Context API 就能够直接经过上下文跨层级获取数据:ide
增长一个名为 ToggleContext.js
的文件做为上下文📜,里头定义一系列须要跨层级使用的 state 和 function函数
import React, { createContext } from 'react' // 1. 使用 createContext 建立上下文 const ToggleContext = createContext({ toggle: true, handleToggle: () => {} }) // 2. 建立 Provider export class ToggleProvider extends React.Component { // 注意书写顺序;handleToggle 做为箭头函数不能 bind 所以须要写在上面;若是不喜欢这样的顺序则能够书写普通函数放在下面但记得 bind handleToggle = () => { this.setState({ toggle: !this.state.toggle }) } // 2-1. 重写 state state = { toggle: true, handleToggle: this.handleToggle } render() { // 2-2. 经过 Provider 组件的 value 将 state 提供出去 return ( <ToggleContext.Provider value={this.state}> {this.props.children} </ToggleContext.Provider> ) } } // 3. 建立 Consumer export const ToggleConsumer = ToggleContext.Consumer 复制代码
上面的代码主要分为三大部分:this
// 建立 Context const ToggleContext = createContext() // 建立 Provider export class ToggleProvider extends React.Component {} // 建立 Consumer export cnost ToggleConsumer = ToggleContext.Consumer 复制代码
咱们理一下步骤🏃spa
createContext
上下文并调用,传入咱们但愿在其余层级组件中使用的 state
和改变 state
的方法,注意这里的 state
和方法只是一个“骨架”,后面的 Provider
会覆盖Provider
这里头维护真正的 state
,并经过 render
函数里面的 Context.Provider
组件的 value
属性提供这些方法Consumer
,直接导出 Context.Consumer
给外部使用便可ToggleProvider
组件包装了一系列共享的状态,为了使用这些组件的状态,咱们直接将其添加到 App 组件中:code
import React from 'react'; import { ToggleProvider } from './ToggleContext' // 1. 获取 Provider function App() { // 2-1. 使用 ToggleProvider 组件 // 2-2. 若是有其余组件同样能够共享 state return ( <ToggleProvider> <Switcher></Switcher> {/* 其余组件仍然能够经过 props 访问到共享的 state */} </ToggleProvider> ); } // ... export default App; 复制代码
使用 Provider 比较简单直接做为父组件包裹在上层便可。若是组件内部有其余多个组件,这些组件均可以共享 Provider 提供的 stateorm
import React from 'react'; import { ToggleProvider, ToggleConsumer } from './ToggleContext' // 1. 获取 Provider 和 Consumer function App() { return ( <ToggleProvider> <Switcher></Switcher> </ToggleProvider> ); } const Switcher = () => { return <Pannel /> } const Pannel = () => { // 在多个层级内直接经过 props 获取 state 和方法,调用方法改变 state return ( <ToggleConsumer> {({ toggle, handleToggle }) => <div onClick={() => handleToggle()}>{ toggle ? '✔' : '❌'}</div>} </ToggleConsumer> ) } export default App; 复制代码
直接在子组件内部经过 props 调用便可blog
另外附上一个简易版的 Context:
import React, { createContext } from "react";
const { Provider, Consumer } = createContext("color"); // 建立 Context 引用 Provider 和 Consumer
class DeliverComponent extends React.Component {
// 维护一个 state
state = {
color: 'orange',
handleClick: () => {
this.setState({ color: 'red' })
}
}
render() {
return (
<Provider value={this.state}>
<MidComponent />
</Provider>
)
}
}
const MidComponent = () => <Receiver />; // 中间包含多层级的组件
const Receiver = () => ( // 须要使用的后代元素使用 Consumer
<Consumer>
{({ color, handleClick }) => <div style={{ color }} onClick={() => { handleClick() }}> Hello, this is receiver.</div>}
</Consumer>
);
const App = () => <DeliverComponent />;
export default App;
复制代码
参考: