I'm in the early process of building a commissioning checklist application for our company. Since the checklist is fairly large (and many of them) I wanted to create a function that maps through an object and after rendering the values written would update the appropriate states with a useState Hook.
The page is rendering without any issues. The problem only appears once the input is changed. Instead of updating the correct state in the object. It seems the logic is adding an additional section in my object and creating another input element.
import React, { useState } from 'react'
const ProjectInfo = () => {
const _renderObject= () => {
return Object.keys(answers).map((obj, i) => {
return(
<div key={obj}>
<label>{answers[obj].question}</label>
<input type="text" onChange={(e, obj) => setAnswer(
{
...answers,
obj:{
value: e.target.value
}})} />
</div>
)
})
}
const [answers, setAnswer] = useState({
11:{
question:"Project Name",
value:""
},
12:{
question:"Project Number",
value:""
}
})
return(
<div>
<section>
{_renderObject()}
</section>
<p>{`Project Number is: ${answers[11].value}`}</p>
<p>{`Project Name is: ${answers[12].value}`}</p>
</div>
)
}
export default ProjectInfo
I was expecting for the state to just update as normal. But what I'm suspecting is in my renderObject method my obj variable for my .map function is not being used inside my setAnswer function and causes another field to be created with a key name of "obj".
If this is the issue is it possible to have the setAnswer function in my renderObject Method to use the "obj" value of the map function and not the actual value of the word obj as key?
If not what would be the best way to approach this? I was thinking of adding a submit button at the bottom of the screen and updating all states with an onClick event listener. But now I'm think I'll have the same issue since the scope of the obj variable isn't resolved.
Any help would be greatly appreciated. I've only been doing this for a couple of months, any advice and feedback would also be appreciated!
You seem to be not using the dynamic key correctly while updating state. Also you need to update the value within the key and not override it. Also obj
shouldn't be the second argument to onChange
instead it must be received from the enclosing scope
const _renderObject= () => {
return Object.keys(answers).map((obj, i) => {
return(
<div key={obj}>
<label>{answers[obj].question}</label>
<input type="text" onChange={(e) => setAnswer(
{
...answers,
[obj]:{
...answers[obj],
value: e.target.value
}})} />
</div>
)
})