committed by
GitHub
10 changed files with 170 additions and 146 deletions
@ -0,0 +1,12 @@ |
|||
const Button = ({theme, children}) => ( |
|||
<button className={theme ? 'dark' : 'light'}> |
|||
{children} |
|||
</button> |
|||
); |
|||
|
|||
// highlight-range{1,3}
|
|||
export default React.forwardRef((props, ref) => ( |
|||
<ThemeContext.Consumer> |
|||
{theme => <Button {...props} theme={theme} ref={ref} />} |
|||
</ThemeContext.Consumer> |
|||
)); |
@ -0,0 +1,22 @@ |
|||
class Button extends React.Component { |
|||
componentDidMount() { |
|||
// highlight-next-line
|
|||
alert(this.props.theme); |
|||
} |
|||
|
|||
render() { |
|||
const {theme, children} = this.props; |
|||
return ( |
|||
<button className={theme ? 'dark' : 'light'}> |
|||
{children} |
|||
</button> |
|||
); |
|||
} |
|||
} |
|||
|
|||
// highlight-range{3}
|
|||
export default props => ( |
|||
<ThemeContext.Consumer> |
|||
{theme => <Button {...props} theme={theme} />} |
|||
</ThemeContext.Consumer> |
|||
); |
@ -1,34 +1,23 @@ |
|||
class Button extends React.Component { |
|||
render() { |
|||
return ( |
|||
<button style={{background: this.props.color}}> |
|||
{this.props.children} |
|||
</button> |
|||
); |
|||
} |
|||
} |
|||
const ThemedButton = props => { |
|||
//highlight-range{1}
|
|||
return <Button theme={props.theme} />; |
|||
}; |
|||
|
|||
class Message extends React.Component { |
|||
render() { |
|||
// highlight-range{1-3}
|
|||
// The Message component must take `color` as as prop to pass it
|
|||
// to the Button. Using context, the Button could connect to the
|
|||
// color context on its own.
|
|||
return ( |
|||
<div> |
|||
<p>{this.props.text}</p> |
|||
<Button color={this.props.color}>Delete</Button> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
// An intermediate component
|
|||
const Toolbar = props => { |
|||
// highlight-range{1-2,5}
|
|||
// The Toolbar component must take an extra theme prop
|
|||
// and pass it to the ThemedButton
|
|||
return ( |
|||
<div> |
|||
<ThemedButton theme={props.theme} /> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
class MessageList extends React.Component { |
|||
class App extends React.Component { |
|||
render() { |
|||
const color = 'purple'; |
|||
const children = this.props.messages.map(message => ( |
|||
<Message text={message.text} color={color} /> |
|||
)); |
|||
return <div>{children}</div>; |
|||
// highlight-range{1}
|
|||
return <Toolbar theme="dark" />; |
|||
} |
|||
} |
|||
|
@ -1,43 +1,33 @@ |
|||
// highlight-range{1}
|
|||
const ColorContext = React.createContext(); |
|||
// Create a theme context, defaulting to light theme
|
|||
// highlight-next-line
|
|||
const ThemeContext = React.createContext('light'); |
|||
|
|||
class Button extends React.Component { |
|||
render() { |
|||
// highlight-range{2-8}
|
|||
return ( |
|||
<ColorContext.Consumer> |
|||
{color => ( |
|||
<button style={{background: color}}> |
|||
{this.props.children} |
|||
</button> |
|||
)} |
|||
</ColorContext.Consumer> |
|||
); |
|||
} |
|||
} |
|||
const ThemedButton = props => { |
|||
// highlight-range{1,3-5}
|
|||
// The ThemedButton receives the theme from context
|
|||
return ( |
|||
<ThemeContext.Consumer> |
|||
{theme => <Button theme={theme} />} |
|||
</ThemeContext.Consumer> |
|||
); |
|||
}; |
|||
|
|||
class Message extends React.Component { |
|||
render() { |
|||
return ( |
|||
<div> |
|||
<p>{this.props.text}</p> |
|||
<Button>Delete</Button> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
// An intermediate component
|
|||
const Toolbar = props => { |
|||
return ( |
|||
<div> |
|||
<ThemedButton /> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
class MessageList extends React.Component { |
|||
class App extends React.Component { |
|||
render() { |
|||
const color = 'purple'; |
|||
const children = this.props.messages.map(message => ( |
|||
<Message text={message.text} /> |
|||
)); |
|||
// highlight-range{2-4}
|
|||
// highlight-range{2,4}
|
|||
return ( |
|||
<ColorContext.Provider value={color}> |
|||
{children} |
|||
</ColorContext.Provider> |
|||
<ThemeContext.Provider value="dark"> |
|||
<Toolbar /> |
|||
</ThemeContext.Provider> |
|||
); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,38 @@ |
|||
// Theme context, default to light theme
|
|||
// highlight-next-line
|
|||
const ThemeContext = React.createContext('light'); |
|||
|
|||
// Signed-in user context
|
|||
// highlight-next-line
|
|||
const UserContext = React.createContext(); |
|||
|
|||
class App extends React.Component { |
|||
static propTypes = { |
|||
theme: PropTypes.string, |
|||
signedInUser: PropTypes.shape({ |
|||
id: number, |
|||
name: string, |
|||
avatar: string, |
|||
}), |
|||
}; |
|||
|
|||
render() { |
|||
// highlight-range{9}
|
|||
return ( |
|||
<ThemeContext.Provider value={this.props.theme}> |
|||
<UserContext.Provider |
|||
value={this.props.signedInUser}> |
|||
<ThemeContext.Consumer> |
|||
{theme => ( |
|||
<UserContext.Consumer> |
|||
{user => ( |
|||
<ProfilePage user={user} theme={theme} /> |
|||
)} |
|||
</UserContext.Consumer> |
|||
)} |
|||
</ThemeContext.Consumer> |
|||
</UserContext.Provider> |
|||
</ThemeContext.Provider> |
|||
); |
|||
} |
|||
} |
@ -1,55 +0,0 @@ |
|||
// Create a theme context, defaulting to light theme
|
|||
// highlight-next-line
|
|||
const ThemeContext = React.createContext('light'); |
|||
|
|||
class ThemeProvider extends React.Component { |
|||
render() { |
|||
// highlight-range{2-4}
|
|||
return ( |
|||
<ThemeContext.Provider value={this.props.theme}> |
|||
{this.props.children} |
|||
</ThemeContext.Provider> |
|||
); |
|||
} |
|||
} |
|||
|
|||
class ThemedButton extends React.Component { |
|||
render() { |
|||
//highlight-range{2-4}
|
|||
return ( |
|||
<ThemeContext.Consumer> |
|||
{theme => <Button theme={theme} />} |
|||
</ThemeContext.Consumer> |
|||
); |
|||
} |
|||
} |
|||
|
|||
const SomeComponent = props => { |
|||
// The ThemedButton receives the theme from context;
|
|||
// SomeComponent does not need to know about it
|
|||
// highlight-range{3}
|
|||
return ( |
|||
<div> |
|||
<ThemedButton /> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
class App extends React.Component { |
|||
render() { |
|||
// The ThemedButton button inside the ThemeProvider
|
|||
// uses the dark theme while the one outside uses the
|
|||
// default light theme
|
|||
// highlight-range{3-5,7}
|
|||
return ( |
|||
<div> |
|||
<ThemeProvider theme="dark"> |
|||
<SomeComponent /> |
|||
</ThemeProvider> |
|||
<div> |
|||
<ThemedButton /> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
} |
Loading…
Reference in new issue