简体   繁体   English

使用useState时如何更改对象中的值

[英]How to change the value in an object when using useState

I'm learning React so far I'm having a problem when I want to click on the Vote button and the vote for that story increases.到目前为止,我正在学习 React,当我想单击“投票”按钮并且对该故事的投票增加时遇到了问题。 Can someone guide me?有人可以指导我吗?

JavaScript code: JavaScript 代码:

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

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."
];

function Button(props) {
  return <button onClick={props.event}>{props.text}</button>;
}

function App() {
  const [selected, setSelected] = useState(0);
  const [points, setPoints] = useState({
    0: 0,
    1: 0,
    2: 0,
    3: 0,
    4: 0,
    5: 0
  });

  function next() {
    setSelected(Math.floor(Math.random() * anecdotes.length));
  }

  function vote() {

  }

  return (
    <>
      <h1>Anecdote of the day</h1>
      <p>{anecdotes[selected]}</p>
      <p>has {points[selected]} votes</p>
      <Button text="Vote" event={vote} />
      <Button text="Next anecdote" event={next} />
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Thank you.谢谢你。

Link: https://codesandbox.io/s/react-b6-usestate-type-2-05q8x链接: https : //codesandbox.io/s/react-b6-usestate-type-2-05q8x

Just simply in the vote function clone the original object with spread syntax first, by doing this you will have a new object called newPoints .只需简单地在vote函数中首先使用扩展语法克隆原始对象,通过这样做,您将拥有一个名为newPoints的新对象。 Then you need to update the selected one by adding newPoints[selected] + 1 to increase the vote numbers.然后您需要通过添加newPoints[selected] + 1来更新选定的一个以增加投票数。 Then it is ready to update with setPoints .然后就可以用setPoints更新了。

Something like this:像这样的东西:

const [selected, setSelected] = useState(0);

const vote = () => {
   const newPoints = {...points};
   newPoints[selected] = newPoints[selected] + 1;
   setPoints(newPoints);
}

Read further here: Spread syntax在此处进一步阅读: 传播语法

I hope that helps!我希望这有帮助!

This should be able to do the trick.这应该可以解决问题。

function vote() {
    let p = {...points};
    p[selected] += 1;
    setPoints(p);
    console.log( points);
  }
  1. I think the most important thing which everyone is missing here is我认为这里每个人都缺少的最重要的东西是

    setPoints( points => { //new Points return newPoints})

    if you set a state from previous value then you need to pass a function for setState to avoid race cases.如果您从以前的值设置状态,那么您需要为 setState 传递一个函数以避免竞争情况。

  2. If the state is an object then there is no use of mutating it since the reference will be the same old one and react does not rerender.如果状态是一个对象,则没有使用对其进行变异,因为引用将是相同的旧引用并且 react 不会重新渲染。

    To solve this issue generally what I do is为了解决这个问题,我通常做的是

    setPoints( points => { let newPoints = JSON.parse(JSON.stringify(points)); //change newPoints; return newPoints })

    The main reason why I go with JSON.parse(JSON.stringiy(points)) rathar than {...points} is because in deeply nested objects the inner objects will also be new objects.我使用JSON.parse(JSON.stringiy(points))而不是{...points}的主要原因是因为在深度嵌套的对象中,内部对象也将是新对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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