Browse Source

Tweak context docs (#766)

main
Dan Abramov 7 years ago
committed by GitHub
parent
commit
f7cf140607
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      examples/context/forwarding-refs-fancy-button.js
  2. 2
      examples/context/higher-order-component-usage.js
  3. 23
      examples/context/motivation-problem.js
  4. 49
      examples/context/motivation-solution.js
  5. 45
      examples/context/multiple-contexts.js
  6. 1
      examples/context/reference-caveats-solution.js

2
examples/context/forwarding-refs-fancy-button.js

@ -8,7 +8,7 @@ class FancyButton extends React.Component {
// Use context to pass the current "theme" to FancyButton. // Use context to pass the current "theme" to FancyButton.
// Use forwardRef to pass refs to FancyButton as well. // Use forwardRef to pass refs to FancyButton as well.
// highlight-range{1,3} // highlight-range{1,4}
export default React.forwardRef((props, ref) => ( export default React.forwardRef((props, ref) => (
<ThemeContext.Consumer> <ThemeContext.Consumer>
{theme => ( {theme => (

2
examples/context/higher-order-component-usage.js

@ -1,7 +1,5 @@
function Button({theme, ...rest}) { function Button({theme, ...rest}) {
// highlight-next-line
return <button className={theme} {...rest} />; return <button className={theme} {...rest} />;
} }
// highlight-next-line
const ThemedButton = withTheme(Button); const ThemedButton = withTheme(Button);

23
examples/context/motivation-problem.js

@ -1,13 +1,15 @@
function ThemedButton(props) { class App extends React.Component {
//highlight-range{1} render() {
return <Button theme={props.theme} />; return <Toolbar theme="dark" />;
}
} }
// An intermediate component
function Toolbar(props) { function Toolbar(props) {
// highlight-range{1-2,5} // highlight-range{1-4,7}
// The Toolbar component must take an extra theme prop // The Toolbar component must take an extra "theme" prop
// and pass it to the ThemedButton // and pass it to the ThemedButton. This can become painful
// if every single button in the app needs to know the theme
// because it would have to be passed through all components.
return ( return (
<div> <div>
<ThemedButton theme={props.theme} /> <ThemedButton theme={props.theme} />
@ -15,9 +17,6 @@ function Toolbar(props) {
); );
} }
class App extends React.Component { function ThemedButton(props) {
render() { return <Button theme={props.theme} />;
// highlight-range{1}
return <Toolbar theme="dark" />;
}
} }

49
examples/context/motivation-solution.js

@ -1,18 +1,26 @@
// Create a theme context, defaulting to light theme // highlight-range{1-4}
// highlight-next-line // Context lets us pass a value deep into the component tree
// without explicitly threading it through every component.
// Create a context for the current theme (with "light" as the default).
const ThemeContext = React.createContext('light'); const ThemeContext = React.createContext('light');
function ThemedButton(props) { class App extends React.Component {
// highlight-range{1,3-5} render() {
// The ThemedButton receives the theme from context // highlight-range{1-3,5}
return ( // Use a Provider to pass the current theme to the tree below.
<ThemeContext.Consumer> // Any component can read it, no matter how deep it is.
{theme => <Button {...props} theme={theme} />} // In this example, we're passing "dark" as the current value.
</ThemeContext.Consumer> return (
); <ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
} }
// An intermediate component // highlight-range{1,2}
// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar(props) { function Toolbar(props) {
return ( return (
<div> <div>
@ -21,13 +29,14 @@ function Toolbar(props) {
); );
} }
class App extends React.Component { function ThemedButton(props) {
render() { // highlight-range{1-3,6}
// highlight-range{2,4} // Use a Consumer to read the current theme context.
return ( // React will find the closest theme Provider above and use its value.
<ThemeContext.Provider value="dark"> // In this example, the current theme is "dark".
<Toolbar /> return (
</ThemeContext.Provider> <ThemeContext.Consumer>
); {theme => <Button {...props} theme={theme} />}
} </ThemeContext.Consumer>
);
} }

45
examples/context/multiple-contexts.js

@ -1,27 +1,9 @@
// Theme context, default to light theme // Theme context, default to light theme
// highlight-next-line
const ThemeContext = React.createContext('light'); const ThemeContext = React.createContext('light');
// Signed-in user context // Signed-in user context
// highlight-next-line
const UserContext = React.createContext(); const UserContext = React.createContext();
// An intermediate component that depends on both contexts
function Toolbar(props) {
// highlight-range{2-10}
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
class App extends React.Component { class App extends React.Component {
render() { render() {
const {signedInUser, theme} = this.props; const {signedInUser, theme} = this.props;
@ -31,9 +13,34 @@ class App extends React.Component {
return ( return (
<ThemeContext.Provider value={theme}> <ThemeContext.Provider value={theme}>
<UserContext.Provider value={signedInUser}> <UserContext.Provider value={signedInUser}>
<Toolbar /> <Layout />
</UserContext.Provider> </UserContext.Provider>
</ThemeContext.Provider> </ThemeContext.Provider>
); );
} }
} }
function Layout() {
return (
<div>
<Sidebar />
<Content />
</div>
);
}
// A component may consume multiple contexts
function Content() {
// highlight-range{2-10}
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}

1
examples/context/reference-caveats-solution.js

@ -1,5 +1,6 @@
class App extends React.Component { class App extends React.Component {
constructor(props) { constructor(props) {
super(props);
// highlight-range{2} // highlight-range{2}
this.state = { this.state = {
value: {something: 'something'}, value: {something: 'something'},

Loading…
Cancel
Save