ReactJS如何更新数组中对象的状态

Posted

技术标签:

【中文标题】ReactJS如何更新数组中对象的状态【英文标题】:ReactJS How to update the state in object which is in the array 【发布时间】:2021-01-24 04:36:41 【问题描述】:

您好,我有一个问题不知道如何解决。

我有一个简单的公式,用户输入 som 输入。之后,当他单击按钮时,名字、姓氏和图片将显示在公式下方。当我点击输入时,它会显示地址和日期。

但是我这样做有问题。在 App.js 中,我有一个初始状态为空数组,点击提交按钮后,用户输入被添加到这个空数组中。在 Suggestions.js 中,我映射了 sugestions 数组以显示来自用户的每个建议。

在 UserInputs.js 中,我有一个状态,我在状态中添加了一个“可见”为 false 并且我想要这样做,当我点击列表中的建议时,它会在此特定建议下方显示描述和日期。

我想这样做。在 App.js 中

const detail = (suggestion) => 
        
        setSuggestions([...suggestions]); //but I don't know how to set state for particular 
                                            suggestion in the array.
      ;

我的代码:

App.js

import React,  useState  from "react";
import Suggestions from "./components/Suggestions";
import UserInputs from "./components/UserInputs";

function App() 
  const [suggestions, setSuggestions] = useState([]);

  const addNewSuggestion = (suggestion) => 
    setSuggestions([suggestion, ...suggestions]);
  ;

  const detail = (suggestion) => 
    
    setSuggestions([...suggestions]);
  ;

  console.log("suggestions", suggestions);

  return (
    <div className="app-container">
      <UserInputs addNewSuggestion=addNewSuggestion></UserInputs>
      <Suggestions suggestions=suggestions detail=detail></Suggestions>
    </div>
  );


export default App;

Suggestions.js

import React from "react";

export default function Suggestions( suggestions, detail ) 
  return (
    <div className="suggestion-container">
      <h1 className="suggestion-heading">Zoznam Podnetov</h1>
      suggestions.map((suggestion, index) => 
        return (
          <div
            key=suggestion.id
            className="suggestion"
            onClick=() => detail(suggestion)
          >
            <div className="suggestion-number">index + 1</div>

            <div className="suggestion-details">
              <div className="suggestion-name">
                suggestion.firstName
                ` $suggestion.lastName`
              </div>

              <div className="suggestion-address">suggestion.address</div>
              suggestion.visible ? (
                <div className="suggestion-description">
                  <p>suggestion.description</p>
                  <p>Podnet bol pridaný: suggestion.date</p>
                </div>
              ) : null
            </div>

            <div className="suggestion-picture">
              <img
                src=suggestion.picture
                
                className="suggestion-picture"
              ></img>
            </div>
          </div>
        );
      )
    </div>
  );

用户输入.js

import React,  useState  from "react";

export default function UserInputs( addNewSuggestion ) 
  const randomId = Math.floor(Math.random() * 1000000);

  const [userInputs, setUserInputs] = useState(
    id: randomId,
    firstName: "",
    lastName: "",
    address: "",
    description: "",
    picture: null,
    date: new Date().toLocaleDateString(),
    visible: true,
  );

  const onInputChange = (event) => 
    setUserInputs(
      ...userInputs,
      [event.target.name]: event.target.value,
    );
  ;

  const fileSelectHandler = (event) => 
    setUserInputs(
      ...userInputs,
      picture: URL.createObjectURL(event.target.files[0]),
    );
  ;

  const onSubmit = (event) => 
    event.preventDefault();

    addNewSuggestion(userInputs);

    setUserInputs(
      id: randomId,
      firstName: "",
      lastName: "",
      address: "",
      description: "",
      picture: null,
      date: new Date().toLocaleDateString(),
      visible: true,
    );
  ;

  return (
    <div>
      <form className="form-container">
        <div className="row">
          <label>Meno</label>
          <input
            autoFocus
            type="text"
            name="firstName"
            value=userInputs.firstName
            onChange=onInputChange
          ></input>
        </div>

        <div className="row">
          <label>Priezvisko</label>
          <input
            type="text"
            name="lastName"
            value=userInputs.lastName
            onChange=onInputChange
          ></input>
        </div>

        <div className="row">
          <label>Adresa</label>
          <input
            type="text"
            name="address"
            value=userInputs.address
            onChange=onInputChange
          ></input>
        </div>

        <div className="row">
          <label>Popis</label>
          <input
            type="text"
            name="description"
            value=userInputs.description
            onChange=onInputChange
          ></input>
        </div>

        <div className="row">
          <input type="file" onChange=fileSelectHandler></input>
        </div>

        <button onClick=onSubmit className="button">
          Odoslať
        </button>
      </form>
    </div>
  );

非常感谢您的帮助。

【问题讨论】:

解决此问题的一种方法是跟踪每个建议的索引(在数组中)(数组索引可能与 DOM 索引一致,但不一定)。然后要更改索引i 中的特定建议,只需更改i 处的数组位置 感谢您的回答。你能把代码的例子发给我吗?因为在 setSuggestions 我需要复制以前的状态,然后更新数组中特定建议的当前状态。我迷路了。 【参考方案1】:

您可以更新建议,其中 id 与输入建议匹配并且只更新它。请在下面找到代码:

const detail = (suggestion) =>  

  let tempSuggestions = suggestions.map( (item) =>   
  if(item.id === suggestion.id) return suggestion
  return item
)
        
setSuggestions([...tempSuggestions]);                                            

【讨论】:

以上是关于ReactJS如何更新数组中对象的状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Reactjs 中的状态对象内将值添加到数组中

ReactJS:如何使用动态键访问和更新嵌套状态对象?

保存状态中的对象数组 - ReactJS

当状态数组中的任何值被修改时,ReactJS 组件状态不会更新

ReactJS:仅更新嵌套状态对象中的特定字段[重复]

ReactJS - 状态数组中的重复对象保持链接