mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-22 11:52:00 +00:00
Added context HOC example to reference
This commit is contained in:
@@ -14,10 +14,10 @@ In a typical React application, data is passed top-down (parent to child) via pr
|
||||
- [Provider](#provider)
|
||||
- [Consumer](#consumer)
|
||||
- [Examples](#examples)
|
||||
- [Static Context](#static-context)
|
||||
- [Dynamic Context](#dynamic-context)
|
||||
- [Consuming Multiple Contexts](#consuming-multiple-contexts)
|
||||
- [Accessing Context in Lifecycle Methods](#accessing-context-in-lifecycle-methods)
|
||||
- [Consuming Context with a HOC](#consuming-context-with-a-hoc)
|
||||
- [Forwarding Refs to Context Consumers](#forwarding-refs-to-context-consumers)
|
||||
- [Caveats](#caveats)
|
||||
- [Legacy API](#legacy-api)
|
||||
@@ -104,6 +104,24 @@ Accessing values from context in lifecycle methods is a relatively common use ca
|
||||
|
||||
`embed:context/lifecycles.js`
|
||||
|
||||
### Consuming Context with a HOC
|
||||
|
||||
Some types of contexts are consumed by many components (e.g. theme or localization). It can be tedious to explicitly wrap each dependency with a `<Context.Consumer>` element. A [higher-order component](/docs/higher-order-components.html) can help with this.
|
||||
|
||||
For example, a button component might consume a theme context like so:
|
||||
|
||||
`embed:context/higher-order-component-before.js`
|
||||
|
||||
That's alright for a few components, but what if we wanted to use the theme context in a lot of places?
|
||||
|
||||
We could create a higher-order component called `withTheme`:
|
||||
|
||||
`embed:context/higher-order-component.js`
|
||||
|
||||
Now any component that depends on the theme context can easy subscribe to it using the `withTheme` function we've created:
|
||||
|
||||
`embed:context/higher-order-component-usage.js`
|
||||
|
||||
### Forwarding Refs to Context Consumers
|
||||
|
||||
One issue with the render prop API is that refs don't automatically get passed to wrapped elements. To get around this, use `React.forwardRef`:
|
||||
|
||||
10
examples/context/higher-order-component-before.js
Normal file
10
examples/context/higher-order-component-before.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const ThemeContext = React.createContext('light');
|
||||
|
||||
function ThemedButton(props) {
|
||||
// highlight-range{2-4}
|
||||
return (
|
||||
<ThemeContext.Consumer>
|
||||
{theme => <button className={theme} {...props} />}
|
||||
</ThemeContext.Consumer>
|
||||
);
|
||||
}
|
||||
7
examples/context/higher-order-component-usage.js
Normal file
7
examples/context/higher-order-component-usage.js
Normal file
@@ -0,0 +1,7 @@
|
||||
function Button({theme, ...rest}) {
|
||||
// highlight-next-line
|
||||
return <button className={theme} {...rest} />;
|
||||
}
|
||||
|
||||
// highlight-next-line
|
||||
const ThemedButton = withTheme(Button);
|
||||
18
examples/context/higher-order-component.js
Normal file
18
examples/context/higher-order-component.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const ThemeContext = React.createContext('light');
|
||||
|
||||
// This function takes a component...
|
||||
// highlight-next-line
|
||||
export function withTheme(Component) {
|
||||
// ...and returns another component...
|
||||
// highlight-next-line
|
||||
return function ThemedComponent(props) {
|
||||
// ... and renders the wrapped component with the context theme!
|
||||
// Notice that we pass through any additional props as well
|
||||
// highlight-range{2-4}
|
||||
return (
|
||||
<ThemeContext.Consumer>
|
||||
{theme => <Component {...props} theme={theme} />}
|
||||
</ThemeContext.Consumer>
|
||||
);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user