while I am creating new “Todo” and modifying the fields are no problem my issue is receiving back the child data when I click the “show all objects” button.
Here is a code example to illustrate my issue:
const CompoOne = () =>{
const [todos, setTodos] = useState([])
const [subject, setSubject] = useState("")
const [priority, setPriority] = useState("")
const addTodo = () => setTodos(
[...todos, { a: "Title", b: "subTitle", c: "content"}]
)
return (
<>
<InputText
value={subject}
setValue={setSubject}
label="subject field"
/>
<InputText
value={priority}
setValue={setPriority}
label="priority field"
/>
<hr />
<h2>Todo:</h2>
<hr />
<button
onClick={()=>addTodo()}
>
add a todo
</button>
<>
{setTodos.map((el,i)=>(
<CompoTwo
todo={el}
setTodos={setTodos}
todos={todos}
key={i}
/>
)}
</>
<button
onClick={()=>console.log(todos)}
>
show all objects
</button>
</>
)
}
const compoTwo = ({ todo, todos, setTodos }) =>{
const [a, setA] = useState("")
const [b, setB] = useState("")
const [c, setC] = useState("")
const handleChange = (e) =>{
const {name, value} = e.target
setTodos((prevState)=>{
//I would like to update the inside the prevState instance
const updatedArray = // something like [...prevState, [name]:value]
// return updatedArray
})
}
return(
<>
<InputText
value={a}
name="a"
onChange={(e)=>setA(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field A"
/>
<InputText
value={b}
name="b"
onChange={(e)=>setB(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field B"
/>
<InputText
value={c}
name="c"
onChange={(e)=>setC(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field C"
/>
</>
)
}
if I click twice on the “add a Todo” button and change one of the field’s values, I will still get the default value
[
{a: "Title", b: "subTitle", c:"content"},
{a: "Title", b: "subTitle", c:"content"},
]
and my purpose would be to get the updated value of the child component.
if you got any idea…
here is the code sandbox link to try and play
thanks in advance
Advertisement
Answer
You can try this and hope it may help you for compoTwo.
Note: You can also set the todo prop value as the initial value of useState.
const compoTwo = ({ todo, todos, setTodos }) =>{
const [a, setA] = useState("")
const [b, setB] = useState("")
const [c, setC] = useState("")
const handleChange = (e) => {
const { name, value } = e.target;
setTodos((prevState) => {
const temp = [...prevState];
const find = temp.find((res) => res.id === todo.id);
if (find) {
find[name] = value;
return temp;
} else {
return prevState;
}
});
};
return(
<>
<InputText
value={a}
name="a"
onChange={(e)=>setA(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field A"
/>
<InputText
value={b}
name="b"
onChange={(e)=>setB(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field B"
/>
<InputText
value={c}
name="c"
onChange={(e)=>setC(e.target.value)}
onBlur={(e) => handleChange(e)}
label="field C"
/>
</>
)
}