首页 > 解决方案 > React hooks:如何使用对象更新状态

问题描述

我有 3 个这样的组件,我如何更新 App 组件中的状态

如何在 Counter 组件中更新状态 onclick

import React, { useState } from 'react'
import Header from './components/Header'
import Counters from './components/Counters'

const App = () => {
  const initialCounters = [
    { id: 1, value: 0 },
    { id: 2, value: 0 },
    { id: 3, value: 0 },
    { id: 4, value: 0 },
  ]
  const [counters, setCounters] = useState(initialCounters)

  const onIncrement = (counter) => {
    console.log(counter)
  }

  return (
    <>
      <Header totalCounters={counters.length} />
      <main className='container'>
        <Counters counters={counters} onIncrement={onIncrement} />
      </main>
    </>
  )
}

export default App

标签: reactjs

解决方案


在您的 Counters 组件中,当您调用 OnIncrement 方法时,您需要将其 id 作为参考传递。

然后在你的 OnIncrement 你这样做

  const onIncrement = (counterId) => {
    const updatededCounters = counters.map((counter) => {
     if(counter.id === counterId){
      counter.value++
      return counter     
      }
      return counter
     })
     setCounters(updatededCounters)
  }

只是为了在您的 Counters 组件中清楚

import React from "react";

const Counters = ({ counters, onIncrement }) => {
  return (
    <>
      {counters.map((counter) => (
        <div key={counter.id}>
          <p>My counter : {counter.value}</p>
          <button onClick={() => onIncrement(counter.id)}>Increment</button>
        </div>
      ))}
    </>
  );
};

父组件的完整代码

import React, { useState } from "react";
import Counters from "./Counters";

const App = () => {
  const initialCounters = [
    { id: 1, value: 0 },
    { id: 2, value: 0 },
    { id: 3, value: 0 },
    { id: 4, value: 0 }
  ];
  const [counters, setCounters] = useState(initialCounters);
  const onIncrement = (counterId) => {
    const updatededCounters = counters.map((counter) => {
      if (counter.id === counterId) {
        counter.value++;
        return counter;
      }
      return counter;
    });
    setCounters(updatededCounters);
  };

  return (
    <>
      <main className="container">
        <Counters counters={counters} onIncrement={onIncrement} />
      </main>
    </>
  );
};

export default App;

Codesandbox 链接:https ://codesandbox.io/s/sad-chebyshev-l4hez?file=/src/App.js:0-725

解释

我所做的 onIncrement 方法很简单:我将创建一个新数组,其中包含我想要在其中编辑的值,然后我将使用这个新数组设置状态。

在 .map() 中,计数器的每个实例都将被循环,因此对于每个实例,我检查其中一个是否是我要更新的那个(与我作为参数接收的 counterId 具有相同的 id)

If so, i edit the value of the current counter and then return the counter instance to allow the loop to continue to the next one.

When the counter id is not the same as the counterId received, i just return the counter without any modification.

So at the end, you will get the same array of values, exepct for the specific counter you incremented where you will see it's value updated by one count

I advice you to read some documentation about .map() function since it's really used in react : https://fr.reactjs.org/docs/lists-and-keys.html

And aswell you coud look into Object.keys() beceause it's often used with .map() aswell if you need to loop through object properties : https://reedbarger.com/how-to-transform-javascript-objects-the-power-of-objectkeys-values-entries/


推荐阅读