Use Actions To Manipulate The Store#
Wiring The Store#
Now that we have our store ready, it's time to connect the store to our code and remove all the unneeded functionality.
The first step is to factor out the Faq
component into a separate file called components/Faq.jsx
.
It is almost an exact copy of App.js
:
1import { useState } from "react";
2import FaqItem from "./FaqItem";
3
4function Faq() {
5 const [faqList, setFaqList] = useState([
6 {
7 question: "What does the Plone Foundation do?",
8 answer: "The mission of the Plone Foundation is to protect and...",
9 },
10 {
11 question: "Why does Plone need a Foundation?",
12 answer: "Plone has reached critical mass, with enterprise...",
13 },
14 ]);
15
16 const [question, setQuestion] = useState("");
17 const [answer, setAnswer] = useState("");
18
19 const onDelete = (index) => {
20 let faq = [...faqList];
21 faq.splice(index, 1);
22 setFaqList(faq);
23 };
24
25 const onChangeAnswer = (e) => {
26 setAnswer(e.target.value);
27 };
28
29 const onChangeQuestion = (e) => {
30 setQuestion(e.target.value);
31 };
32
33 const onEdit = (index, question, answer) => {
34 const faq = [...faqList];
35 faq[index] = { question, answer };
36 setFaqList(faq);
37 };
38
39 const onSubmit = (e) => {
40 e.preventDefault();
41 setFaqList([...faqList, { question, answer }]);
42 setQuestion("");
43 setAnswer("");
44 };
45
46 return (
47 <div>
48 <ul>
49 {faqList.map((item, index) => (
50 <FaqItem
51 key={index}
52 question={item.question}
53 answer={item.answer}
54 index={index}
55 onDelete={onDelete}
56 onEdit={onEdit}
57 />
58 ))}
59 </ul>
60 <form onSubmit={onSubmit}>
61 <label>
62 Question:{" "}
63 <input
64 name="question"
65 type="text"
66 value={question}
67 onChange={onChangeQuestion}
68 />
69 </label>
70 <label>
71 Answer:{" "}
72 <textarea name="answer" value={answer} onChange={onChangeAnswer} />
73 </label>
74 <input type="submit" value="Add" />
75 </form>
76 </div>
77 );
78}
79
80export default Faq;
Next we will create an App
component with just the store and a reference to our newly created Faq
component:
1import { Provider } from "react-redux";
2import { createStore } from "redux";
3
4import rootReducer from "./reducers";
5import Faq from "./components/Faq";
6
7import "./App.css";
8
9const store = createStore(rootReducer);
10
11const App = () => {
12 return (
13 <Provider store={store}>
14 <Faq />
15 </Provider>
16 );
17};
18
19export default App;
Use The Data From The Store#
Now that we have our store wired, we can start using the store data instead of our local state.
We will use the hook useSelector
for extracting the data from the store, and useDispatch
for dispatching the action which is needed by the component.
2import { useSelector,useDispatch } from "react-redux";
3import { addFaqItem } from "../actions";
We can remove all the edit and delete references, since those will be handled by the FaqItem
to clean up our code.
We will also change the onSubmit
handler to use the addFaqItem
action.
The result will be as follows:
1import { useState } from "react";
2import { useSelector, useDispatch } from "react-redux";
3
4import { addFaqItem } from "../actions";
5import FaqItem from "./FaqItem";
6
7function Faq() {
8 const faqList = useSelector((state) => state.faq);
9 const dispatch = useDispatch();
10
11 const [question, setQuestion] = useState("");
12 const [answer, setAnswer] = useState("");
13
14 const onChangeAnswer = (e) => {
15 setAnswer(e.target.value);
16 };
17
18 const onChangeQuestion = (e) => {
19 setQuestion(e.target.value);
20 };
21
22 const onSubmit = (e) => {
23 e.preventDefault();
24 setQuestion("");
25 dispatch(addFaqItem(question, answer));
26 setAnswer("");
27 };
28
29 return (
30 <div>
31 <ul>
32 {faqList.map((item, index) => (
33 <FaqItem
34 key={index}
35 question={item.question}
36 answer={item.answer}
37 index={index}
38 />
39 ))}
40 </ul>
41 <form onSubmit={onSubmit}>
42 <label>
43 Question:{" "}
44 <input
45 name="question"
46 type="text"
47 value={question}
48 onChange={onChangeQuestion}
49 />
50 </label>
51 <label>
52 Answer:{" "}
53 <textarea name="answer" value={answer} onChange={onChangeAnswer} />
54 </label>
55 <input type="submit" value="Add" />
56 </form>
57 </div>
58 );
59}
60
61export default Faq;
Exercise#
Now that we factored out the edit and delete actions from the Faq
component, update the FaqItem
component to call the actions we created for our store.