Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
139 views
in Technique[技术] by (71.8m points)

reactjs - React - how to update state with dynamic properties without defining it in state first?

const [number, setNumber] = React.useState({})

The way Im doing it below does not work:

   setNumber(prevNumber => ({
  ...prevNumber,
  [num]: (prevNumber[num] + 1) || 0,
}))

The only way to get it to work is when i define the properties as below:

const [number, setNumber] = React.useState({
 1: 0,
 2: 0,
 3: 0,
 4: 0,
 5: 0,
})

I dont know how many properties I will have (maybe 1-5 or 1-10 for example) and dont want to pre define all of them. Any help would be great. Thank you.

Update: 'full code':

// what i get is:{4: 4, 5: 1}
//what I wanted and get if i have initialState is:   {1: 0, 2: 0, 3: 0, 4: 4, 5: 1}
const reviews = [
  { title: "movie1", rating: 4 },
  { title: "movie2", rating: 5 },
  { title: "movie3", rating: 4 },
  { title: "movie4", rating: 4 },
  { title: "movie4", rating: 4 }
];
function App() {
  const [number, setNumber] = useState({ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 });

  const func = (num) => {
    setNumber((prevNumber) => ({
      ...prevNumber,
      [num]: (prevNumber[num] || 0) + 1 || 0
    }));
  };
  const getNumbers = () => {
    return reviews.map((review) => {
      func(review.rating);
    });
  };

  console.log("number: ", number);
  return (
    <div>
      <button onClick={getNumbers}>helo</button>
    </div>
  );
}
question from:https://stackoverflow.com/questions/65940727/react-how-to-update-state-with-dynamic-properties-without-defining-it-in-state

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

prevNumber[num] could be undefined, so you need a fallback for that.

Try this: [num]: ((prevNumber[num] || 0) + 1) || 0,

After clarifying what you need, here is an updated fiddle.

Since you do not have the numbers below 4, they will never be set because num will never be 1 for example.

So you would need to check if the numbers below are already present and if not, fill those with 0.

const lowerNumbers = Array.from(Array(num)).reduce((aggregate,_,i) => {
    aggregate[i] = aggregate[i] || 0
    return aggregate
    }, {
      ...prevNumber,
      [num]: (prevNumber[num] || 0) + 1
    })
    return lowerNumbers
  });

This takes the current numbers, adds one to the number that will be increased. It creates an array with the lower numbers and checks if those are already present and if not, fills them with 0.

{ "0": 0, "1": 0, "2": 0, "3": 0, "4": 4, "5": 1 }


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...