可以获得与 Redux 类似功能的两个钩子函数: useReducer 和 useContext.
如果组件的状态简单,用 useState, 反之,可以转而用 useReducer, 从而将逻辑从组件中移到一个单独的函数中去,使我们的组件更易于管理。
useReducer 直白地说,现在有一组数据,要对一个这组数据进行各种操作,例如读写删除等等,就可以将各种操作的逻辑统一集中写到一个这个数据的 reducer 函数中去,对应各种操作, 返回对应的数据,而不是将各种逻辑分散到组件的各处。useReducer 与 Redux 极其相似。
例子:
import React, { useState, useEffect, useReducer } from "react";
import ReactDOM from "react-dom";
import reportWebVitals from "./reportWebVitals";
const notesReducer = (state, action) => {
switch (action.type) {
case "POPULATE_NOTES":
return action.notes;
case "ADD_NOTE":
return [...state, action.note];
case "REMOVE_NOTE":
return state.filter((note) => note.title !== action.title);
default:
return state;
}
};
const NoteApp = () => {
const [notes, dispatch] = useReducer(notesReducer, []);
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
useEffect(() => {
const notes = JSON.parse(localStorage.getItem("notes"));
if (notes) {
dispatch({ type: "POPULATE_NOTES", notes });
}
}, []);
useEffect(() => {
console.log("useEffect ran!!");
localStorage.setItem("notes", JSON.stringify(notes));
}, [notes]);
const addNote = (e) => {
e.preventDefault();
dispatch({ type: "ADD_NOTE", note: { title, body } });
setTitle("");
setBody("");
};
const removeNote = (title) => {
dispatch({ type: "REMOVE_NOTE", title });
};
return (
<div>
<h1>Notes</h1>
{notes.map((note) => (
<Note key={note.title} note={note} removeNote={removeNote} />
))}
<p>================ Add note =============</p>
<form onSubmit={addNote}>
<input value={title} onChange={(e) => setTitle(e.target.value)} />
<textarea value={body} onChange={(e) => setBody(e.target.value)} />
<button>add note</button>
</form>
</div>
);
};
const Note = ({ note, removeNote }) => {
useEffect(() => {
console.log("Setting up effect!");
return () => {
console.log("A note is unmounted!");
};
}, []);
return (
<div>
<h3>{note.title}</h3>
<p>{note.body} </p>
<button onClick={() => removeNote(note.title)}>X</button>
</div>
);
};
ReactDOM.render(
<React.StrictMode>
<NoteApp />
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
|