如何在我的 React 应用程序中使用 useState 挂钩给出的 setState 方法增加选定的状态对象索引的计数

How do I increment the count of a selected index of state object using setState method given by useState hook in my react application

目标:当投票按钮发生点击事件时,将给定数组的索引更新为1

我的代码:我有一个应用程序组件,其中有 2 个状态对象和 1 个数组

const App = () => {
    const anecdotes = [
        'If it hurts, do it more often',
        'Adding manpower to a late software project makes it later!',
        'The first 90 percent of the code accounts for the first 90 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
        'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
        'Premature optimization is the root of all evil.',
        'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.'
    ]

    // to select anecdotes at random
    const [selected, setSelected] = useState(0);

    // elements in anecdotes
    let n = anecdotes.length;
    const [points, setPoints] = useState(() => Array(n).fill(0));

    // to use with setSelected 
    const generateRandomNumber = (min, max) => {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min) + min); 
    }

    // eventHandler
    const handleClickNext = () => {
        return setSelected(generateRandomNumber(0, n))
    }

    const handleClickVote = () => {
        const copy = [...points]
        console.log(copy);
        console.log(selected);
        console.log(copy[selected]);
        console.log(points);
        return setPoints([
            copy[selected] += 1
        ])
    }

    return (
        <>
            <h1>anecdoteZ</h1>
           // code...
        </>
    )
}

export default App;

Objective:该应用程序显示轶事数组中的随机引述以及轶事投票计数和为轶事投票的能力。

问题:我认为问题是我的handleClickVote功能

 const handleClickVote = () => {
        const copy = [...points]
        console.log(copy);
        console.log(selected);
        console.log(copy[selected]);
        console.log(points);
        return setPoints([
            copy[selected] += 1
        ])
    }

代码在显示的第一个轶事上工作正常,但是当我单击 next quote 按钮并对其他引号进行投票时,它在控制台中 returns NaN 因为我正在记录结果。另外我认为我使用 setPoints 错误地设置了数组的状态。 我不想直接改变状态,我想创建一个副本并改变它来更新我的 points 数组的状态。

NB 这是我的应用组件 returns

<>
            <h1>anecdoteZ</h1>
            <span anecdotes={anecdotes} selected={selected}>
                {anecdotes[selected]}
            </span>
            <br />
            <br />
            <span points={points} selected={selected}>has {points[selected]} votes</span>
            <br />
            <button onClick={handleClickVote}>vote</button>
            <button onClick={handleClickNext}>
                next anecdote
            </button>
            <br />
            <br />
            <span>Top voted anecdote</span>
        </>

首先,当您将轶事的长度传递给生成随机数时,它应该是 anecdotes.length - 1

也不需要 return setPoints - 这可能是你的问题

方法handleClickVote 将值设置为长度为1 的数组。 我无法对其进行测试,但我建议将其更改为:

copy[selected] += 1;
return setPoints(copy);

您假设正确,问题出在 handleClickVote 函数上。目前,在第一次投票时,您将状态设置为一个只有一个元素的数组。

return setPoints([       // <<-- new array starts here
    copy[selected] += 1  // <<-- it's only element, will be the the result of
                         //      the increment of whatever is in copy[selected] plus 1
]);

您想要的是更新 copy 中的任何内容,并将 copy 指定为新状态。例如:

copy[selected]++;
return setPoints(copy);

或者(借用 ),简单地:

const handleClickVote = () => {
    return setPoints(current => Object.assign([], current, {
      [selected]: current[selected] + 1
    }));
}