Use Initial Form Data To Edit An Item#
Two Modes For The FAQ Item#
We will use inline editing to edit an item.
Create a button to switch to "edit" mode.
This mode should be set in the state.
Change the render method to show a form (similar to the "add" form) in "edit" mode, and the view we currently have in the "view" mode.
The onSave
handler can be a dummy handler for now.
First we will focus on the two modes.
Solution
1import { useState } from "react";
2import "./FaqItem.css";
3import PropTypes from "prop-types";
4
5const FaqItem = (props) => {
6 const [isAnswer, setAnswer] = useState(false);
7 const [isEditMode, setIsEditMode] = useState(false);
8
9 const toggle = () => {
10 setAnswer(!isAnswer);
11 };
12 const ondelete = () => {
13 props.onDelete(props.index);
14 };
15
16 const onEdit = () => {
17 setIsEditMode(true);
18 };
19
20 const onSave = (e) => {
21 e.preventDefault();
22 setIsEditMode(false);
23 };
24
25 return (
26 <>
27 {isEditMode ? (
28 <li className="faq-item">
29 <form onSubmit={onSave}>
30 <label>
31 Question:
32 <input name="question" />
33 </label>
34 <label>
35 Answer:
36 <textarea name="answer" />
37 </label>
38 <input type="submit" value="Save" />
39 </form>
40 </li>
41 ) : (
42 <li className="faq-item">
43 <h2 className="question" onClick={toggle}>
44 {props.question}
45 </h2>
46 {isAnswer && <p>{props.answer}</p>}
47 <button onClick={ondelete}>Delete</button>
48 <button onClick={onEdit}>Edit</button>
49 </li>
50 )}
51 </>
52 );
53};
54
55FaqItem.propTypes = {
56 question: PropTypes.string.isRequired,
57 answer: PropTypes.string.isRequired,
58 index: PropTypes.number.isRequired,
59 onDelete: PropTypes.func.isRequired,
60};
61
62export default FaqItem;
--- a/src/components/FaqItem.jsx
+++ b/src/components/FaqItem.jsx
@@ -4,6 +4,7 @@ import PropTypes from "prop-types";
const FaqItem = (props) => {
const [isAnswer, setAnswer] = useState(false);
+ const [isEditMode, setIsEditMode] = useState(false);
const toggle = () => {
setAnswer(!isAnswer);
@@ -12,14 +13,42 @@ const FaqItem = (props) => {
props.onDelete(props.index);
};
+ const onEdit = () => {
+ setIsEditMode(true);
+ };
+
+ const onSave = (e) => {
+ e.preventDefault();
+ setIsEditMode(false);
+ };
+
return (
- <li className="faq-item">
- <h2 className="question" onClick={toggle}>
- {props.question}
- </h2>
- {isAnswer && <p>{props.answer}</p>}
- <button onClick={ondelete}>Delete</button>
- </li>
+ <>
+ {isEditMode ? (
+ <li className="faq-item">
+ <form onSubmit={onSave}>
+ <label>
+ Question:
+ <input name="question" />
+ </label>
+ <label>
+ Answer:
+ <textarea name="answer" />
+ </label>
+ <input type="submit" value="Save" />
+ </form>
+ </li>
+ ) : (
+ <li className="faq-item">
+ <h2 className="question" onClick={toggle}>
+ {props.question}
+ </h2>
+ {isAnswer && <p>{props.answer}</p>}
+ <button onClick={ondelete}>Delete</button>
+ <button onClick={onEdit}>Edit</button>
+ </li>
+ )}
+ </>
);
};
Wiring Everything Together#
Create a controlled form like the add form, and pass an onEdit
handler to the FaqItem
component, like we did with the onDelete
.
FaqItem.jsx
1import { useState } from "react";
2import "./FaqItem.css";
3import PropTypes from "prop-types";
4
5const FaqItem = (props) => {
6 const [isAnswer, setAnswer] = useState(false);
7 const [isEditMode, setIsEditMode] = useState(false);
8 const [question, setQuestion] = useState("");
9 const [answer, setQuestionAnswer] = useState("");
10
11 const toggle = () => {
12 setAnswer(!isAnswer);
13 };
14 const ondelete = () => {
15 props.onDelete(props.index);
16 };
17
18 const onEdit = () => {
19 setIsEditMode(true);
20 setQuestionAnswer(props.answer);
21 setQuestion(props.question);
22 };
23
24 const onChangeAnswer = (e) => {
25 setQuestionAnswer(e.target.value);
26 };
27 const onChangeQuestion = (e) => {
28 setQuestion(e.target.value);
29 };
30
31 const onSave = (e) => {
32 e.preventDefault();
33 setIsEditMode(false);
34 props.onEdit(props.index, question, answer);
35 };
36
37 return (
38 <>
39 {isEditMode ? (
40 <li className="faq-item">
41 <form onSubmit={onSave}>
42 <label>
43 Question:
44 <input
45 name="question"
46 value={question}
47 onChange={onChangeQuestion}
48 />
49 </label>
50 <label>
51 Answer:
52 <textarea
53 name="answer"
54 value={answer}
55 onChange={onChangeAnswer}
56 />
57 </label>
58 <input type="submit" value="Save" />
59 </form>
60 </li>
61 ) : (
62 <li className="faq-item">
63 <h2 className="question" onClick={toggle}>
64 {props.question}
65 </h2>
66 {isAnswer && <p>{props.answer}</p>}
67 <button onClick={ondelete}>Delete</button>
68 <button onClick={onEdit}>Edit</button>
69 </li>
70 )}
71 </>
72 );
73};
74
75FaqItem.propTypes = {
76 question: PropTypes.string.isRequired,
77 answer: PropTypes.string.isRequired,
78 index: PropTypes.number.isRequired,
79 onDelete: PropTypes.func.isRequired,
80 onEdit: PropTypes.func.isRequired,
81};
82
83export default FaqItem;
--- a/src/components/FaqItem.jsx
+++ b/src/components/FaqItem.jsx
@@ -5,6 +5,8 @@ import PropTypes from "prop-types";
const FaqItem = (props) => {
const [isAnswer, setAnswer] = useState(false);
const [isEditMode, setIsEditMode] = useState(false);
+ const [question, setQuestion] = useState("");
+ const [answer, setQuestionAnswer] = useState("");
const toggle = () => {
setAnswer(!isAnswer);
@@ -15,11 +17,21 @@ const FaqItem = (props) => {
const onEdit = () => {
setIsEditMode(true);
+ setQuestionAnswer(props.answer);
+ setQuestion(props.question);
+ };
+
+ const onChangeAnswer = (e) => {
+ setQuestionAnswer(e.target.value);
+ };
+ const onChangeQuestion = (e) => {
+ setQuestion(e.target.value);
};
const onSave = (e) => {
e.preventDefault();
setIsEditMode(false);
+ props.onEdit(props.index, question, answer);
};
return (
@@ -29,11 +41,19 @@ const FaqItem = (props) => {
<form onSubmit={onSave}>
<label>
Question:
- <input name="question" />
+ <input
+ name="question"
+ value={question}
+ onChange={onChangeQuestion}
+ />
</label>
<label>
Answer:
- <textarea name="answer" />
+ <textarea
+ name="answer"
+ value={answer}
+ onChange={onChangeAnswer}
+ />
</label>
<input type="submit" value="Save" />
</form>
@@ -57,6 +77,7 @@ FaqItem.propTypes = {
answer: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
onDelete: PropTypes.func.isRequired,
+ onEdit: PropTypes.func.isRequired,
};
export default FaqItem;
App.js
1import { useState } from "react";
2import "./App.css";
3import FaqItem from "./components/FaqItem";
4
5function App() {
6 const [faqList, setFaqList] = useState([
7 {
8 question: "What does the Plone Foundation do?",
9 answer: "The mission of the Plone Foundation is to protect and...",
10 },
11 {
12 question: "Why does Plone need a Foundation?",
13 answer: "Plone has reached critical mass, with enterprise...",
14 },
15 ]);
16
17 const [question, setQuestion] = useState("");
18 const [answer, setAnswer] = useState("");
19
20 const onDelete = (index) => {
21 let faq = [...faqList];
22 faq.splice(index, 1);
23 setFaqList(faq);
24 };
25
26 const onChangeAnswer = (e) => {
27 setAnswer(e.target.value);
28 };
29
30 const onChangeQuestion = (e) => {
31 setQuestion(e.target.value);
32 };
33
34 const onEdit = (index, question, answer) => {
35 const faq = [...faqList];
36 faq[index] = { question, answer };
37 setFaqList(faq);
38 };
39
40 const onSubmit = (e) => {
41 e.preventDefault();
42 setFaqList([...faqList, { question, answer }]);
43 setQuestion("");
44 setAnswer("");
45 };
46
47 return (
48 <div>
49 <ul>
50 {faqList.map((item, index) => (
51 <FaqItem
52 key={index}
53 question={item.question}
54 answer={item.answer}
55 index={index}
56 onDelete={onDelete}
57 onEdit={onEdit}
58 />
59 ))}
60 </ul>
61 <form onSubmit={onSubmit}>
62 <label>
63 Question:{" "}
64 <input
65 name="question"
66 type="text"
67 value={question}
68 onChange={onChangeQuestion}
69 />
70 </label>
71 <label>
72 Answer:{" "}
73 <textarea name="answer" value={answer} onChange={onChangeAnswer} />
74 </label>
75 <input type="submit" value="Add" />
76 </form>
77 </div>
78 );
79}
80
81export default App;
--- a/src/App.js
+++ b/src/App.js
@@ -31,6 +31,12 @@ function App() {
setQuestion(e.target.value);
};
+ const onEdit = (index, question, answer) => {
+ const faq = [...faqList];
+ faq[index] = { question, answer };
+ setFaqList(faq);
+ };
+
const onSubmit = (e) => {
e.preventDefault();
setFaqList([...faqList, { question, answer }]);
@@ -48,6 +54,7 @@ function App() {
answer={item.answer}
index={index}
onDelete={onDelete}
+ onEdit={onEdit}
/>
))}
</ul>