preface

React provides a Context for broadcasting data. The consumer component only needs to use specific methods to get the broadcast data, instead of using the method of layers of props. Context can also be used to share data between components, such as the router component in react-router:

.render() {
    return (
      <RouterContext.Provider
        value={{
          history: this.props.history.location: this.state.location.match: Router.computeRootMatch(this.state.location.pathname),
          staticContext: this.props.staticContext
        }}
      >
        <HistoryContext.Provider
          children={this.props.children || null}
          value={this.props.history}
        />
      </RouterContext.Provider>); }...Copy the code

After wrapping the component with a Provider, you can then retrieve the latest history data directly from the context.

Under what circumstances need to use the Context: react.docschina.org/docs/contex…

Consider: before using react.docschina.org/docs/contex…

React.createContext

Use to create a Context object that contains the Provider and Consumer components. The Provider component can provide a context for consumption by the Consumer component. You can also specify a default value for the Context object when creating it:

const NewContext = React.createContext(defaultValue);
Copy the code

If the Consumer component does not match the Provider in its tree, the defaultValue will be used.

If you assign the Provider’s value to undefined directly, the consumer component’s defaultValue will not take effect

Context.Provider

A Provider can provide a context for the consuming component, and the internal consuming component can consume the value by putting the data to be broadcast into it:

const{Provider} = NewContext; . <Provider value='provider'>
 <Button />
</Provider>
...
Copy the code

Providers can be nested, but consumers will only consume the nearest Provider.

If the value of the Provider changes, all of its internal consumer components will be re-rendered, even if shouldComponentUpdate is used for optimization.

If objects are provided to the Provider, unnecessary rendering can also occur in the consumers component, since each value gets a new object when the parent component rerenders.

The workaround is to store the object in state:

const App = () = > {
  const [state, setState] = useState({});
  useEffect(() = >{... setState({theme'#fff'})... })return(
  <NewContext.Provider value={state}>
   <Button />  
  </NewContext.Provider>)}Copy the code

Class.contextType

We can retrieve the Context inside the component by assigning the contextType property to the Context object: contextType; contextType; contextType; contextType; contextType; contextType; contextType

class App extends React.Component {...componentDidMount(){...let value = this.context ... }...render(){...let value = this.context
    ...
  }
}
App.contextType = NewContext
Copy the code

Context can be retrieved in any lifecycle of the component. The static keyword can also be used for initialization:

class App extends React.Component {
  static contextType = NewContext
 render(){...let value = this.context ... }}Copy the code

Context.Consumer

ContextType applies only to class components. For function components, use the Consutmer component to retrieve the context: contextType contextType

const App = () = > {
  return(
   <NewContext.Consumer>{context => {// get the context and do some other logic // Return the React node return<Button style={{background: context.theme}} / >
      }}
    </NewContext.Consumer>)}Copy the code

The Consumer component needs a function to receive the current context, which returns a React node.

Context.displayName

The Context object receives a displayName property of type string, which React DevTools uses to determine what the Context is displaying:

const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';

<MyContext.Provider> // "myDisplayName. Provider" is in DevTools
<MyContext.Consumer> // "myDisplayName. Consumer" is in DevTools
Copy the code

useContext

UseContext is a react-provided hooks API that can be used to retrieve the corresponding Context provided by the Context object:

// context.js
export const NewContext = React.createContext(defaultValue);

// app.js
import {NewContext} from './context'
import {Buttons} from './buttons'
const App = () = >{...return(
   <NewContext.Provider value={{theme: '#fff'}} >.<Buttons />
    </NewContext.Provider>)}// buttons.js
import {Button} from './button'
const Buttons = () = >{...return(... <Button /> ... ) }// button.js
import {useContext} from 'react'
import {NewContext} from './context'
const Button = () = > {
  const context = useContext(NewContext)
  
  return (
   <button style={{background: context.theme}} >button</button>)}Copy the code

When the most recent < newContext. Provider> update is made to the component’s upper layer, the Hook triggers a rerender and uses the latest context value passed to the NewContext Provider. Even if the ancestor uses React. Memo or shouldComponentUpdate, it will be rerendered when the component itself uses useContext.

reference

[1] react.docschina.org/docs/contex…

[2] react.docschina.org/docs/hooks-…