1/*
2 A common use case is to access a child imperatively:
3*/
4
5function TextInputWithFocusButton() {
6 const inputEl = useRef(null);
7 const onButtonClick = () => {
8 // `current` points to the mounted text input element
9 inputEl.current.focus();
10 };
11 return (
12 <>
13 <input ref={inputEl} type="text" />
14 <button onClick={onButtonClick}>Focus the input</button>
15 </>
16 );
17}
1const initialState = {count: 0};
2
3function reducer(state, action) {
4 switch (action.type) {
5 case 'increment':
6 return {count: state.count + 1};
7 case 'decrement':
8 return {count: state.count - 1};
9 default:
10 throw new Error();
11 }
12}
13
14function Counter() {
15 const [state, dispatch] = useReducer(reducer, initialState);
16 return (
17 <>
18 Count: {state.count}
19 <button onClick={() => dispatch({type: 'decrement'})}>-</button>
20 <button onClick={() => dispatch({type: 'increment'})}>+</button>
21 </>
22 );
23}
1function init(initialCount) { return {count: initialCount};}
2function reducer(state, action) {
3 switch (action.type) {
4 case 'increment':
5 return {count: state.count + 1};
6 case 'decrement':
7 return {count: state.count - 1};
8 case 'reset': return init(action.payload); default:
9 throw new Error();
10 }
11}
12
13function Counter({initialCount}) {
14 const [state, dispatch] = useReducer(reducer, initialCount, init); return (
15 <>
16 Count: {state.count}
17 <button
18 onClick={() => dispatch({type: 'reset', payload: initialCount})}> Reset
19 </button>
20 <button onClick={() => dispatch({type: 'decrement'})}>-</button>
21 <button onClick={() => dispatch({type: 'increment'})}>+</button>
22 </>
23 );
24}
1// useReducer is a React hook function that accepts a reducer function, and an initial state this hook function returns an array with 2 values
2const [state, dispatch] = useReducer(reducer, initialState);
3
4
5const initialState = {
6 darkMode: false,
7};
8
9
10function reducer(state, action) {
11 switch (action.type) {
12 case 'DARK_MODE_ON':
13 return { ...state, darkMode: true };
14 case 'DARK_MODE_OFF':
15 return { ...state, darkMode: false };
16 default:
17 return state;
18 }
19}
1import React, { useState, useReducer } from "react";
2import ReactDOM from "react-dom";
3
4import "./styles.css";
5
6function reducer(state, action) {
7 switch (action.type) {
8 case "add":
9 return [...state, action.item];
10 case "remove":
11 return [
12 ...state.slice(0, action.index),
13 ...state.slice(action.index + 1)
14 ];
15 default:
16 throw new Error();
17 }
18}
19
20function FavoriteMovies() {
21 const [movies, dispatch] = useReducer(reducer, [{ name: "Heat" }]);
22 const [newMovie, setNewMovie] = useState("");
23
24 const handleAddClick = () => {
25 if (newMovie === "") {
26 return;
27 }
28 dispatch({ type: "add", item: { name: newMovie } });
29 setNewMovie("");
30 };
31
32 return (
33 <>
34 <div className="movies">
35 {movies.map((movie, index) => {
36 return (
37 <Movie
38 movie={movie}
39 onRemove={() => dispatch({ type: "remove", index })}
40 />
41 );
42 })}
43 </div>
44 <div className="add-movie">
45 <input
46 type="text"
47 value={newMovie}
48 onChange={event => setNewMovie(event.target.value)}
49 />
50 <button onClick={handleAddClick}>Add movie</button>
51 </div>
52 </>
53 );
54}
55
56function Movie({ movie, onRemove }) {
57 return (
58 <div className="movie">
59 <span>{movie.name}</span>
60 <button onClick={onRemove}>Remove</button>
61 </div>
62 );
63}
64
65function App() {
66 return (
67 <div className="App">
68 <h2>My favorite movies</h2>
69 <FavoriteMovies />
70 </div>
71 );
72}
73
74const rootElement = document.getElementById("root");
75ReactDOM.render(<App />, rootElement);
76