Home > Software design >  Changing the value of object's property inside of a mapped array (buttons added through map fun
Changing the value of object's property inside of a mapped array (buttons added through map fun

Time:09-27

I mapped an array of objects and added a button for each object.

How can I make those buttons increase the "points" value ( 1) on click, but only for the item the button clicked on & store it in the failedArr array.

failedArr array:

[   {name: 'English', points: 0}, 
    {name: 'Agriculture', points: 0}, 
    {name: 'Medicine', points:0}, 
    {name:'German',points:0}, 
    {name:'Math',points:0},
    {name:'Economics', points:0}, 
    {name:'Literature', points:0}, 
    {name:'Gardening', points:0}
]

Mapping:

{failedArr.map(key => (
    <div key={key.name}>
        <button>Add point</button>
        <p>{key.name} - {key.points}</p>
    </div>
))}

Whole component file:

import {fetchAll} from '../AppFetch';
import {useEffect, useState} from 'react';

export default function Subjects() {

  const [data, setData] = useState({});
    
  useEffect(( ) => {
    fetchAll("http://localhost:3000/example.json", setData)
  }, []);

  const failedArr = [];

  for(let i=0; i<Object.entries(data).length; i  ){
    const status = Object.values(data)[i];

    for(let j=0; j < Object.keys(status).length; j  ){
      const failed=Object.entries(status)[j][1]
      
      failedArr.push(failed[j])
    }
  }
  
  return <div className="row">
    {failedArr.map(key => (
      <div key={key.name}>
        <button>Add point</button>
        <p>{key.name} - {key.points}</p>
      </div>
    ))}
  </div>;
}

CodePudding user response:

Can be done like this:

// import React from "react";

const failedArr = [
  { name: "English" },
  { name: "Agriculture" },
  { name: "Medicine" },
  { name: "German" },
  { name: "Math" },
  { name: "Economics" },
  { name: "Literature" },
  { name: "Gardening" },
];

const App = () => {
  const [state, setState] = React.useState({});

  const buttonClickHandler = ({ target: { name } }) => {
    setState({ ...state, [name]: (state[name] || 0)   1 });
  };

  return (
    <div>
      {failedArr.map(({ name }) => (
        <div key={name}>
          <button name={name} onClick={buttonClickHandler}>
            Add point
          </button>
          <p>
            {name} - {state[name] || 0}
          </p>
        </div>
      ))}
      <div>State:{JSON.stringify(state)}</div>
    </div>
  );
};

// export default App;

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

CodePudding user response:

You need to store failedArr as a state variable and do something like

const [failedArr, setFailedArr] = useState([]);
const handleClick = index =>{
  setFailedArray(prevState => prevState.map((item,i)=>{
    if(i===index){
      return {...item, points: item.points   1}
    }
  return item
  })
}

{failedArr.map((key, i) => (
  <div key={key.name}>
    <button onClick = {(i)=>handleClick(i)}>Add point</button>
    <p>{key.name} - {key.points}</p>
  </div>
))}
  • Related