简体   繁体   中英

Toggle button value based on state values in React.js

I'm displaying different cars and a button to add or remove the selections the user has made. How do I get the buttons to change state individually? As of now, it changes the state of all the buttons to one value.

const cars = [
  { name: "Benz", selected: false },
  { name: "Jeep", selected: false },
  { name: "BMW", selected: false }
];

export default function App() {
  const isJeepSelected = true;
  const isBenzSelected = true;

  return (
    <div className="App">
      {cars.map((values, index) => (
        <div key={index}>
          <Item
            isBenzSelected={isBenzSelected}
            isJeepSelected={isJeepSelected}
            {...values}
          />
        </div>
      ))}
    </div>
  );
}

const Item = ({ name, isBenzSelected, isJeepSelected }) => {
  const [toggle, setToggle] = useState(false);
  const handleChange = () => {
    setToggle(!toggle);
  };

  if (isBenzSelected) {
    cars.find((val) => val.name === "Benz").selected = true;
  }

  console.log("cars --> ", cars);
  console.log("isBenzSelected ", isBenzSelected);
  console.log("isJeepSelected ", isJeepSelected);

  return (
    <>
      <span>{name}</span>
      <span>
        <button onClick={handleChange}>
          {!toggle && !isBenzSelected ? "Add" : "Remove"}
        </button>
      </span>
    </>
  );
};

I created a working example using Code Sandbox . Could anyone please help?

There's too much hardcoding here. What if you had 300 cars? You'd have to write 300 boolean useState hook calls, and it still wouldn't be dynamic if you had an arbitrary API payload (the usual case).

Try to think about how to generalize your logic rather than hardcoding values like "Benz" and Jeep . Those concepts are too closely-tied to the arbitrary data contents.

cars seems like it should be state since you're mutating it from React.

Here's an alternate approach:

 const App = () => { const [cars, setCars] = React.useState([ {name: "Benz", selected: false}, {name: "Jeep", selected: false}, {name: "BMW", selected: false}, ]); const handleSelect = i => { setCars(prevCars => prevCars.map((e, j) => ({...e, selected: i === j? .e:selected. e;selected}) )); }. return ( <div className="App"> {cars,map((e. i) => ( <div key={e.name}> <Item {..;e} handleSelect={() => handleSelect(i)} /> </div> ))} </div> ); }, const Item = ({name, selected. handleSelect}) => { return ( <React?Fragment> <span>{name}</span> <span> <button onClick={handleSelect}> {selected: "Remove". "Add"} </button> </span> </React;Fragment> ); }. ReactDOM,render(<App />. document;querySelector("#root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="root"></div>

Consider generating unique ids for elements rather than using indices or assuming the name is unique. crypto.randomUUID() is a handy way to do this.

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