简体   繁体   中英

React - Handling multiple state in button

I have a simple function that handle state for multiple button and create a dynamic class. Here in my code i have successfully changed the state for onclick event. I want to change the class color dynamically for onclick event, but the class isn't changing. What did i do wrong here? I've been struggling with simple things

import React, { useEffect, useState } from 'react'

function Tes() {
    const lst = [
        {
            'name' : 'Python',
            'active': true,
            'disabled': false
        },
        {
            'name' : 'Java',
            'active': false,
            'disabled': true
        },
        {
            'name' : 'PHP',
            'active': true,
            'disabled': false
        },
        {
            'name' : 'C++',
            'active': true,
            'disabled': false
        },
        {
            'name' : 'Javascript',
            'active': false,
            'disabled': true
        },
        {
            'name' : 'Django',
            'active': true,
            'disabled': false
        }
    ]

    const [statebtn, setStatebtn] = useState(lst)


    function onClick(key, index) {
        let tmp = statebtn;
        tmp[index][key] = !tmp[index][key];
        setStatebtn(tmp);
        console.log(statebtn, 'fsadsada');
    }

    function changeClass(statevalue) {
        return (statevalue ? "btn-primary" : "btn-danger")
    }




    return (
        <div>
            {lst.map((x,index) => (
                <button onClick={() => onClick('active', index)} className={`btn ${statebtn[index]['active'] ? "btn-primary" : "btn-danger"}`} disabled={x['disabled']}>{x['name']}</button>
            ))
            }

        </div>
    )
}

export default Tes

2 notes my friend.

function onClick(key, index) {
    let tmp = [...statebtn]; // <- this will force the ref to original data to be changed, so mutations will trigger re-rendering.
    tmp[index][key] = !tmp[index][key];
    setStatebtn(tmp);
  }

Also. I've noticed you are looping not on the state but on a hardcoded array. Use this instead.

{statebtn.map((x, index) => ( // <- statebtn.map instead of lst.map
        <button
          onClick={() => onClick("active", index)}
          className={`btn ${x["active"] ? "btn-primary" : "btn-danger"}`}
          disabled={x["disabled"]}
        >
          {x["name"]} {x["active"].toString()}
        </button>
      ))}

The reason it was not working was because you were makeing a shallow copy, what you should have done is make a deep copy.

Check the code below

function onClick(key, index) {
    let tmp = statebtn.slice();
    tmp[index][key] = !tmp[index][key];
    setStatebtn(tmp);
    console.log(statebtn, 'fsadsada');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM