├── .gitignore
├── README.md
├── package.json
├── pages
├── _app.js
├── api
│ └── hello.js
└── index.js
├── public
├── favicon.ico
└── vercel.svg
├── styles
├── Home.module.css
└── globals.css
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # How I Manage State in React
2 |
3 | When I'm building a React app, how do I manage state?
4 |
5 | ## App State
6 |
7 | Keep state as low as possible.
8 |
9 | 1. Local State
10 | 2. Lift State
11 | 3. Global State (with contexts)
12 |
13 | Once you are dealing with Global State, you're welcome to use MobX, Redux, Overmind, Zustand, Recoil, etc... or just stick with `useState`.
14 |
15 | ## External Data
16 |
17 | React Query, SWR, Apollo Client, urql
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-state",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "9.5.3",
12 | "react": "16.13.1",
13 | "react-dom": "16.13.1",
14 | "react-query": "^2.23.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default (req, res) => {
4 | res.statusCode = 200
5 | res.json({ name: 'John Doe' })
6 | }
7 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import { useState, memo, createContext, useContext } from "react";
2 | import { useQuery } from "react-query";
3 | import styles from "../styles/Home.module.css";
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | const HomeContent = memo(() => {
14 | return (
15 |
16 |
17 |
18 |
19 | );
20 | });
21 |
22 | const CountryContext = createContext();
23 |
24 | function CountryProvider({ children }) {
25 | const [country, setCountry] = useState("CA");
26 |
27 | return (
28 |
29 | {children}
30 |
31 | );
32 | }
33 |
34 | async function fetchCountry(country) {
35 | const response = await fetch(
36 | `https://restcountries.eu/rest/v2/alpha/${country}`
37 | );
38 | const data = await response.json();
39 | return data;
40 | }
41 |
42 | function CountryDetails() {
43 | const { country } = useContext(CountryContext);
44 | const { data, isLoading, error } = useQuery([country], fetchCountry);
45 |
46 | if (isLoading) return loading...;
47 | if (error) return oop!! error occurred;
48 |
49 | return (
50 |
51 |
{country}
52 |
{JSON.stringify(data, null, 2)}
53 |
54 | );
55 | }
56 |
57 | function CountryPicker() {
58 | const { country, setCountry } = useContext(CountryContext);
59 |
60 | return (
61 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leighhalliday/managing-state-react/8e15afdaf961b784a4c01848e816382e9971f3f4/public/favicon.ico
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | }
9 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
--------------------------------------------------------------------------------