-2

I'm working on a basic Todo app. I'm storing the todo items in state as an array of objects. The object key is the todo item, the value is either true(done) or false(not done). When I click a button to check off an item, I want to change the value of the todo item as well as change the style of the element to indicate it is done.

this.state = {items: [...{"todo item": false}]}

handleClick(e, item, index){
        e.preventDefault()
        let newState = [...this.state.items];
        if(this.state.items[index][Object.keys(item)] == false){
            //blue = done
            e.target.parentNode.style.color = 'blue';
            newState[index][Object.keys(item)] = true;
        }
        this.setState({items:newState})
        console.log(this.state.items[index])
}

This is not working. I'm assuming that it is because setState is asynchronous. I thought to try it this way because I want to send my state object to my database so I can keep track of the "doneness" of each item. I don't want to remove the item from my items array. Any help would be very much appreciated. Let me know if more information is needed!

b c
  • 53
  • 4
  • Does this answer your question? [Why calling setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately) – Dexygen Jul 20 '21 at 20:47
  • Define "not working". What result are you observing vs. what you are expecting? If you're just referring to the last `console.log` statement then your assumption is correct, `setState` is asynchronous. Knowing that, what "isn't working" here? Is the state successfully updating and you're just not observing it correctly? Ignoring your `console.log` statement, is the state actually getting updated in the application? – David Jul 20 '21 at 20:47
  • @David, it doesn't appear to be updating state properly or changing the color of the parent element. – b c Jul 20 '21 at 20:52
  • @bc: Can you provide a [mcve] demonstrating? Either here as a stack snippet or externally on something like CodeSandbox? For starters, this isn't how I would change an element's style in React. That should be driven by state. Because if the style in the rendering is based on state then this change won't affect anything since the component will re-render. – David Jul 20 '21 at 20:53
  • 1
    Why exactly are you indexing with `[Object.keys(item)]`? There should literally be no reason for you to do this – Kelvin Schoofs Jul 20 '21 at 20:59
  • `[...{"todo item": false}]` looks like a error as well. – Emile Bergeron Jul 20 '21 at 22:50

1 Answers1

0

I don't think setState is the issue here? The issue is how you modify the color.

For the color, I would use a ternary based off the state variable rather than DOM manipulation. Something like this answer: ternary operator in jsx to include html with react

If the state isn't uploading (log it at the start of the function so you can see what it is after the run rather than immediately after), then that's a separate issue.

ᴓᴓᴓ
  • 1,178
  • 1
  • 7
  • 18