by elizaveta anatskaya
As the data flow is one direction in React. When any data is required at nth level, the data will have to be passed as a prop through all the child components.
Renaming props halfway through
Over-forwarding props
Refactor the shape of some data
Context API is a way to enable components to share some data without explicitly passing via each component manually.
Context is like a global object to the React component sub-tree.
Context should be used only for the data, which will be used at various levels in the React component tree.
For better maintainability React allows us to create multiple contexts in one app.
export const CountryContext = createContext({});
export const LanguageContext = createContext('en');
export const CountryContext = React.createContext({});
export const LanguageContext = React.createContext('en');
import { createContext } from 'react' ;
export const ThemeContext = createContext('light');
import React from 'react';
export const ThemeContext = React.createContext('light');
createContext returns a pair of Provider and Consumer components and takes on defaultValue of the current context
const { Provider, Consumer} = ThemeContext;
ThemeContext.Provider;
ThemeContext.Consumer;
– is a component that enables Consumers to subscribe to the context changes. The provider accepts a value prop and the data in this prop is available to all the child consumers.
class App extends Component {
const ThemeContext = createContext('defaultValue');
// const {Provider} = createContext('defaultValue');
render() {
return (
<ThemeContext.Provider value={'light'}}>
<Header toggleTheme={this.toggleTheme}/>
<Body/>
</ThemeContext.Provider>
// <Provider value={'light'}}>
// <Header toggleTheme={this.toggleTheme}/>
// <Body/>
// </Provider>
);
}
}
export default App;
— is a getter of context. The components can subscribe to context values by wrapping the Consumer around it
import React, { Component } from 'react'
export default class Body extends Component {
const ThemeContext = React.createContext('defaultValue');
// const { Consumer } = createContext('defaultValue');
render() {
return (
<ThemeContext.Consumer>
{
(theme) => (
<div
className="body"
style={{color: theme.fontColor}}>
Some text goes here
</div>
)
}
</ThemeContext.Consumer>
// <Consumer>
// {}
// </Consumer>
)
}
}
import React, { Component } from 'react'
export default class Body extends Component {
const ThemeContext = React.createContext('defaultValue');
static contextType = ThemeContext;
render() {
const theme = this.context;
return (
<div
className="body"
style={{color: theme.fontColor}}
>
Some text goes here
</div>
)
}
}
— is a getter of context. The components can subscribe to context values by wrapping the Consumer around it
import React, { Component } from 'react'
export default class Body extends Component {
const ThemeContext = React.createContext('defaultValue');
// const { Consumer } = createContext('defaultValue');
render() {
return (
<ThemeContext.Consumer>
{
(theme) => (
<div
className="body"
style={{color: theme.fontColor}}>
Some text goes here
</div>
)
}
</ThemeContext.Consumer>
// <Consumer>
// {}
// </Consumer>
)
}
}
const value = useContext(MyContext);
Correct: useContext(MyContext)
Incorrect: useContext(MyContext.Consumer)
Incorrect: useContext(MyContext.Provider)
don’t forget that the argument to useContext must be the context object itself:
import React from 'react';
import ThemeContext from './ThemeContext';
const C = () => {
const {color} = React.useContext(ThemeContext);
return (
<p style={{ color }}>
Hello World
</p>
);
};
Accepts a context object (the value returned from React.createContext) and returns the current context value for that context.
React Context will trigger a re-render on each update, and optimizing it manually can be really tough
With the useContext API and React Hooks, there is no need to install external libraries
Every time the HOC is created, the component instance starts with a fresh state, and so the buttons’ themes are independent of each other.