Home > Net >  How can I correctly use setState to change an object inside my state
How can I correctly use setState to change an object inside my state

Time:09-15

I am using setState to change isHeld: false to true. It works I can see it in the console but I am not returning everything back. App.js:38 Uncaught TypeError: Cannot read properties of undefined (reading 'map') at App.js:38:1 this is the Error I get after using setState

React.useEffect(()=> {
    fetch("https://opentdb.com/api.php?amount=5&category=27&difficulty=easy&type=multiple")
    .then(res => res.json())
    .then((data) => setState(data.results.map(item => ({
      myQuestions: item.question,
      buttons: item.incorrect_answers.concat(item.correct_answer).map(item => ({use:item, isHeld:false, id:uuidv4()}))
    
    }))))
    
  } , [])

This is where im setting my state from the api and creating objects to store my api information.

const [state , setState] = React.useState ([])
const [object , setObject] = React.useState([])


console.log(state)

 
const getGame = state.map(item => <Quiz
  buttons ={item.buttons.map(item => item)}
  handleClick = {(e) => handleClick(e.target.name)}
  questions ={item.myQuestions}

  /> )




  function handleClick(e) {
    setState(prevState => prevState.map(item => item.buttons.map(item => item.id === e ? 
      {...item, isHeld: !item.isHeld} : item )))

At function handleClick im using spread operator to return back my state but Im pretty sure I am not returning right. Here is what I get back

(5) [Array(4), Array(4), Array(4), Array(4), Array(4)]
0
: 
Array(4)
0
: 
{use: 'Homo Ergaster', isHeld: true, id: '9c06df0a-9723-45b0-88ff-44831af1021e'}
1
: 
{use: 'Homo Erectus', isHeld: false, id: '67c6a404-ac77-418f-abe1-2c43f98fe6fb'}
2
: 
{use: 'Homo Neanderthalensis', isHeld: false, id: '9efc29f2-7327-405c-b5d6-b05dd7f060d4'}
3
: 
{use: 'Homo Sapiens', isHeld: false, id: '96f30d43-1b2a-4500-bdd3-021102f5652b'}
length
: 
4
[[Prototype]]
: 
Array(0)
1
: 
Array(4)
0
: 
{use: 'Cub', isHeld: false, id: '3adf25eb-4cb2-4842-92e1-ae5bb548bc5c'}
1
: 
{use: 'Chick', isHeld: false, id: 'e11a4476-49ba-4c9a-a7f7-1c2fc668f461'}
2
: 
{use: 'Kid', isHeld: false, id: '195bcba3-156f-4b91-a916-8cc1d1a9871b'}
3
: 
{use: 'Pup', isHeld: false, id: 'a3e153b6-74cd-4a6c-80da-82f26414e3c3'}
length
: 
4
[[Prototype]]
: 
Array(0)
2
: 
(4) [{…}, {…}, {…}, {…}]
3
: 
(4) [{…}, {…}, {…}, {…}]
4
: 
(4) [{…}, {…}, {…}, {…}]
length
: 
5
[[Prototype]]
: 
Array(0)

And this is What I should getting back

(5) [{…}, {…}, {…}, {…}, {…}]
0
: 
buttons
: 
(4) [{…}, {…}, {…}, {…}]
myQuestions
: 
"What is the scientific name for modern day humans?"
[[Prototype]]
: 
Object
1
: 
buttons
: 
(4) [{…}, {…}, {…}, {…}]
myQuestions
: 
"What do you call a baby bat?"
[[Prototype]]
: 
Object
2
: 
{myQuestions: 'Which class of animals are newts members of?', buttons: Array(4)}
3
: 
{myQuestions: 'What is the collective noun for a group of crows?', buttons: Array(4)}
4
: 
{myQuestions: 'What is the name of a rabbit&#039;s abode?', buttons: Array(4)}
length
: 
5

Its missing the myQuestions object entirely. If anyone could help me use setState to return my nested object properly id greatly appreciate it. Thank you.

CodePudding user response:

The error seems to be in your handleClick function. This should fix it:

function handleClick(e) {
    setState(prevState => prevState.map(item => ({ 
        ...item,
        buttons: item.buttons.map(btn => 
          btn.id === e ? {...btn, isHeld: !btn.isHeld} : btn),
    })))
}

You were returning a different state for the item itself.

  • Related