更改映射数组中对象 属性 的值(通过映射函数添加的按钮)

Changing the value of object's property inside of a mapped array (buttons added through map function)

我映射了一个对象数组并为每个对象添加了一个按钮。

如何让这些按钮在点击时增加“点数”值 (+ 1),但仅限于按钮点击的项目并将其存储在 failedArr 数组中。

failedArr数组:

[   {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}
]

映射:

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

整个组件文件:

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>;
}

您需要将 failedArr 存储为状态变量并执行类似

的操作
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>
))}

可以这样做:

// 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>

维护状态中的失败数据,然后当在状态上单击按钮时 map,如果对象名称不等于每个按钮上的数据名称属性,则返回未更改的对象,或更新的对象。

const { useState } = React;

function Example({ data }) {

  const [failed, setFailed] = useState(data);

  function handleClick(e) {
    const name = e.target.dataset.name;
    const update = failed.map(obj => {
      if (obj.name === name) {
        return { ...obj, points: ++obj.points };
      }
      return obj;
    });
    setFailed(update);
  }

  return (
    <div className="row">
    {failed.map(obj => (
      <div key={obj.name}>
        <button
          onClick={handleClick}
          data-name={obj.name}
          >Add point
        </button>
        <p>{obj.name} - {obj.points}</p>
      </div>
    ))}
    </div>
  );
}

const data = [
  {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}
];

// Render it
ReactDOM.render(
  <Example data={data} />,
  document.getElementById("react")
);
<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="react"></div>