Skip to content

Commit c69df63

Browse files
author
Horacio Herrera
committed
refactor context exercise
1 parent bff587c commit c69df63

File tree

6 files changed

+75
-51
lines changed

6 files changed

+75
-51
lines changed

src/components/patterns/Context/Page.jsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React from "react"
2-
import Example from './example'
3-
import Exercise from './exercise'
1+
import React from "react";
2+
import Example from "./example";
3+
import Exercise from "./exercise";
44

55
const Page = () => (
66
<div>
@@ -15,8 +15,8 @@ const Page = () => (
1515
We are going to create a <strong>Theme Switcher</strong> component using
1616
Context. If you see{" "}
1717
<code>src/components/patterns/Context/exercise/theme.js</code>, there are{" "}
18-
<strong>2 themes defined</strong>. You should be able to toggle between these 2
19-
themes.
18+
<strong>2 themes defined</strong>. You should be able to toggle between
19+
these 2 themes.
2020
</p>
2121
<p>This component should:</p>
2222
<ul>
@@ -29,18 +29,22 @@ const Page = () => (
2929
<code>styled-components</code>
3030
</li>
3131
</ul>
32+
<p>
33+
In order to check if the theme is actually changing, you can refactor the{" "}
34+
<code>Hero</code> component (
35+
<code>src/components/patterns/Context/exercise/components/Hero.jsx</code>)
36+
</p>
3237
<p>
3338
Also, in order to toggle the theme, you need to use the{" "}
3439
<code>ThemeContext.Consumer</code> in order to get access to the function
35-
that toggles the state in your ThemeProvider. You have some hints here:
36-
-EXAMPLE THEME-
40+
that toggles the state in your ThemeProvider.
3741
</p>
3842
<Exercise />
3943
<hr />
4044
<h3>Bonus Exercise</h3>
4145
<p>
4246
Implement the Redux Provider in
43-
src/components/patterns/Context/xbonus/Provider.js. Once implemented, use
47+
<code>src/components/patterns/Context/xbonus/Provider.js</code>. Once implemented, use
4448
it in Root.js
4549
</p>
4650
</div>
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import React from "react";
2-
import { ThemeContext } from "./ThemeContext";
2+
// import { ThemeContext } from "./ThemeContext";
33
import Button from "./Button";
44
import Hero from "./Hero";
55

6+
/*
7+
TODO: implement a Consumer from your ThemeContext.
8+
with this consumer you can pass the function to toggle
9+
the theme to this button in the `onClick` prop.
10+
*/
11+
612
const App = () => (
7-
<ThemeContext.Consumer>
8-
{({ setValue }) => (
9-
<Hero>
10-
<Button variant="secondary" onClick={setValue}>
11-
Theme Toggle
12-
</Button>
13-
</Hero>
14-
)}
15-
</ThemeContext.Consumer>
13+
<Hero>
14+
<Button>Theme Switcher</Button>
15+
</Hero>
1616
);
1717

1818
export default App;

src/components/patterns/Context/exercise/components/Button.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ const StyledButton = styled.button`
55
padding: 8px 16px;
66
border-radius: 3px;
77
border: none;
8-
9-
background-color: ${({variant, theme}) => theme.colors[variant] || "white"};
108
color: white;
9+
background-color: black;
1110
`
1211

13-
const Button = ({onClick, children, ...rest}) => (
12+
const dummyFunction = () => console.log('BUTTON CLICKED!');
13+
14+
const Button = ({onClick = dummyFunction, children, ...rest}) => (
1415
<StyledButton onClick={onClick} {...rest}>{children}</StyledButton>
1516
)
1617

src/components/patterns/Context/exercise/components/Hero.jsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,26 @@ const Wrapper = styled("div")`
77
align-items: center;
88
justify-content: center;
99
flex-direction: column;
10-
background-color: ${({theme}) => theme.colors.background};
10+
1111
`
12+
/*
13+
after implementing the ThemeProvider, you should be able to add this next line to the `Wrapper` with no errors:
14+
15+
background-color: ${({theme}) => theme.background};
16+
17+
*/
1218

1319
const Heading = styled.h1`
1420
text-align: center;
1521
font-family: Arial, Helvetica, sans-serif;
16-
color: ${({theme}) => theme.colors.primary};
22+
1723
`
24+
/*
25+
after implementing the ThemeProvider, you should be able to add this next line to the `Heading` with no errors:
26+
27+
color: ${({theme}) => theme.foreground};
28+
29+
*/
1830

1931
const Hero = ({children}) => (
2032
<Wrapper>

src/components/patterns/Context/exercise/components/ThemeContext.jsx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,42 @@ import React from 'react'
22
import themes from '../theme'
33
import { ThemeProvider as StyledProvider } from 'styled-components'
44

5-
export const ThemeContext = React.createContext({});
5+
// First you need to create your `ThemeContext` (use React.CreateContext());
6+
// you need to export this also..
67

78
class ThemeProvider extends React.Component {
9+
10+
// You should heep track of some sort of state to toggle the theme from `light` to `dark`
11+
// (see the themes.js file)
812
state = {
9-
theme: "light"
13+
theme: "???"
1014
}
1115

1216
handleThemeToggle = () => {
13-
this.setState(prevState => ({theme: prevState.theme === 'light' ? 'dark' : 'light'}))
17+
/*
18+
Toggle the theme state using `this.setState`.
19+
remember you can call this function with a funcion as a parameter:
20+
`this.setState(prevState => {}); // prevState is a reference to the actual previous state.
21+
remember that `this.setState` is asynchronous
22+
TODO: link to setState documentation!
23+
*/
1424
}
15-
1625
render() {
17-
const { theme } = this.state;
18-
const { children } = this.props;
19-
console.log('theme => ', themes[theme]);
26+
const { children } = this.props
27+
/*
28+
you should replace the `div` here with your ThemeContext provider and the StyledProvider. you can see an example of this in the next links:
29+
- https://www.styled-components.com/docs/api#themeprovider
30+
- https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
31+
32+
The value of your context should be the current theme, and also your `handleThemeToggle` function.
33+
this is needed so we can have access to this function in other parts of our code, and effectively toggle the theme.
34+
35+
=> you can do this in `src/components/patterns/Context/exercise/components/App.jsx`
36+
*/
2037
return (
21-
<ThemeContext.Provider value={{theme, setValue: this.handleThemeToggle}}>
22-
<StyledProvider theme={themes[theme]}>
23-
{children}
24-
</StyledProvider>
25-
</ThemeContext.Provider>
38+
<div>
39+
{children}
40+
</div>
2641
)
2742
}
2843
}
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
1-
const light = {
2-
colors: {
3-
primary: '#07c',
4-
secondary: '#3f714c',
5-
background: '#f6f6ff'
1+
const themes = {
2+
light: {
3+
foreground: '#000000',
4+
background: '#eeeeee',
65
},
7-
}
8-
9-
const dark = {
10-
colors: {
11-
primary: '#3f714c',
12-
secondary: '#07c',
13-
background: '#ffefd5'
6+
dark: {
7+
foreground: '#ffffff',
8+
background: '#222222',
149
}
1510
}
1611

17-
export default {
18-
light,
19-
dark
20-
}
12+
export default themes

0 commit comments

Comments
 (0)