|
|
|
|
@@ -24,7 +24,7 @@ As your components grow in complexity, it can get harder to see at a glance all
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
import AddTask from './AddTask.js';
|
|
|
|
|
import TaskList from './TaskList.js';
|
|
|
|
|
|
|
|
|
|
@@ -80,7 +80,7 @@ const initialTasks = [
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js AddTask.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function AddTask({onAddTask}) {
|
|
|
|
|
const [text, setText] = useState('');
|
|
|
|
|
@@ -104,7 +104,7 @@ export default function AddTask({onAddTask}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js TaskList.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function TaskList({tasks, onChangeTask, onDeleteTask}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -462,7 +462,7 @@ You probably won't need to do this yourself, but this is similar to what React d
|
|
|
|
|
Finally, you need to hook up the `tasksReducer` to your component. Import the `useReducer` Hook from React:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Then you can replace `useState`:
|
|
|
|
|
@@ -494,7 +494,7 @@ Now it's fully wired up! Here, the reducer is declared at the bottom of the comp
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import AddTask from './AddTask.js';
|
|
|
|
|
import TaskList from './TaskList.js';
|
|
|
|
|
|
|
|
|
|
@@ -575,7 +575,7 @@ const initialTasks = [
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js AddTask.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function AddTask({onAddTask}) {
|
|
|
|
|
const [text, setText] = useState('');
|
|
|
|
|
@@ -599,7 +599,7 @@ export default function AddTask({onAddTask}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js TaskList.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function TaskList({tasks, onChangeTask, onDeleteTask}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -679,7 +679,7 @@ If you want, you can even move the reducer to a different file:
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import AddTask from './AddTask.js';
|
|
|
|
|
import TaskList from './TaskList.js';
|
|
|
|
|
import tasksReducer from './tasksReducer.js';
|
|
|
|
|
@@ -763,7 +763,7 @@ export default function tasksReducer(tasks, action) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js AddTask.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function AddTask({onAddTask}) {
|
|
|
|
|
const [text, setText] = useState('');
|
|
|
|
|
@@ -787,7 +787,7 @@ export default function AddTask({onAddTask}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js TaskList.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function TaskList({tasks, onChangeTask, onDeleteTask}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -890,7 +890,7 @@ Just like with [updating objects](/learn/updating-objects-in-state#write-concise
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useImmerReducer} from 'use-immer';
|
|
|
|
|
import { useImmerReducer } from 'use-immer';
|
|
|
|
|
import AddTask from './AddTask.js';
|
|
|
|
|
import TaskList from './TaskList.js';
|
|
|
|
|
|
|
|
|
|
@@ -965,7 +965,7 @@ const initialTasks = [
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js AddTask.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function AddTask({onAddTask}) {
|
|
|
|
|
const [text, setText] = useState('');
|
|
|
|
|
@@ -989,7 +989,7 @@ export default function AddTask({onAddTask}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js TaskList.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function TaskList({tasks, onChangeTask, onDeleteTask}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1127,10 +1127,10 @@ This means that your action object should have a `type: 'changed_selection'`. Yo
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1210,7 +1210,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1277,10 +1277,10 @@ Here is the example updated to dispatch the corresponding messages:
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1363,7 +1363,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1421,10 +1421,10 @@ Currently, pressing "Send" doesn't do anything. Add an event handler to the "Sen
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1507,7 +1507,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js active
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1560,10 +1560,10 @@ There are a couple of ways you could do it in the "Send" button event handler. O
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1646,7 +1646,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js active
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1708,10 +1708,10 @@ However, _from the user's perspective_, sending a message is a different action
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1800,7 +1800,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js active
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -1905,10 +1905,10 @@ The `[key]: value` [computed property](https://developer.mozilla.org/en-US/docs/
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -1997,7 +1997,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -2082,10 +2082,10 @@ Here is the complete solution:
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from 'react';
|
|
|
|
|
import { useReducer } from 'react';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -2183,7 +2183,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -2270,10 +2270,10 @@ Recall that a reducer function takes two arguments--the current state and the ac
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from './MyReact.js';
|
|
|
|
|
import { useReducer } from './MyReact.js';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -2347,7 +2347,7 @@ export function messengerReducer(state, action) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js MyReact.js active
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export function useReducer(reducer, initialState) {
|
|
|
|
|
const [state, setState] = useState(initialState);
|
|
|
|
|
@@ -2383,7 +2383,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -2444,10 +2444,10 @@ Dispatching an action calls a reducer with the current state and the action, and
|
|
|
|
|
<Sandpack>
|
|
|
|
|
|
|
|
|
|
```js App.js
|
|
|
|
|
import {useReducer} from './MyReact.js';
|
|
|
|
|
import { useReducer } from './MyReact.js';
|
|
|
|
|
import Chat from './Chat.js';
|
|
|
|
|
import ContactList from './ContactList.js';
|
|
|
|
|
import {initialState, messengerReducer} from './messengerReducer';
|
|
|
|
|
import { initialState, messengerReducer } from './messengerReducer';
|
|
|
|
|
|
|
|
|
|
export default function Messenger() {
|
|
|
|
|
const [state, dispatch] = useReducer(messengerReducer, initialState);
|
|
|
|
|
@@ -2521,7 +2521,7 @@ export function messengerReducer(state, action) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js MyReact.js active
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export function useReducer(reducer, initialState) {
|
|
|
|
|
const [state, setState] = useState(initialState);
|
|
|
|
|
@@ -2560,7 +2560,7 @@ export default function ContactList({contacts, selectedId, dispatch}) {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```js Chat.js hidden
|
|
|
|
|
import {useState} from 'react';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
export default function Chat({contact, message, dispatch}) {
|
|
|
|
|
return (
|
|
|
|
|
|