【问题标题】:Failed to trigger re-rendering of list of elements after updating one of the elements from the list更新列表中的元素之一后无法触发重新呈现元素列表
【发布时间】:2021-12-05 20:16:03
【问题描述】:

我有一个在 React Hooks 的组件中呈现的对象列表。 我正在使用来自 API 后端的 GET 请求来设置初始状态。 我尝试做的是使用 PUT 请求将列表中的元素更新到 API,然后再次使用 GET 请求重新渲染对象列表,以使用来自 API 的新更新版本设置对象列表的状态.

这是一个人的财产结构:

person {
 id: null,
 index: null
 name: "",
}

这是一个代码示例:

const [people, setPeople] = useState([]);

const personInitialState = {
 id: null,
 index: null,
 name: ""
}

const [selectedPerson, setSelectedPerson] = useState(personInitialState);

useEffect(() => {
  retrievePeople();
}, []);

const retrievePeople = () => {
  PeopleService.getAll()
          .then(response => {
            setPeople(response.data);
          })
          .catch(e => {
            console.log(e);
  });
}

const updatePerson = (person) => {
        PeopleService.update(person)
            .then(response => {
                setSelectedPerson(response.data);
            })
            .catch(e => {
                console.log(e);
        });
}

const handleUpdatePerson = (person) => {
        let newIndex = person.index + 10;
        person.index = newIndex;
        updatePerson(person);
        retrievePeople();
}


return (
        <ul>
        {people.map((person) => ( 
            <li key={person.id}>
                <span>[{person.index}] {person.name}</span>
                <button onClick={() => handleUpdatePerson(person)}>Change index</button>
            </li>
        ))}
        </ul>
);
  1. 我认识到的是,更新特定元素后,后端的数据更新成功,但列表不会重新渲染,除非我重新加载页面。

  2. 顺便说一下,在下面解释的场景中,重新渲染成功发生了:

  • 我单击了元素一的按钮,该按钮应该更新元素索引并触发重新渲染,但没有发生
  • 当我第二次单击此按钮或与列表中的元素相关的其他按钮之一时,重新渲染立即开始工作。 (对我来说这真的很奇怪)
  1. 问题:我是 React 和 React Hooks 的新手,如果有人解释为什么最后一个场景(第 2 点)会发生以及如何在更新列表中的元素后触发元素的重新渲染,我将不胜感激。

  2. 最后一点是我尝试了另一种方法并且它有效,但我不确定这是否是正确的方法,因为我分别更新前端和后端中的元素,这可能导致值不一致在我看来。下面的例子。

根据第 4 点,函数 handleUpdatePerson 看起来像这样

const handleUpdatePerson = (person) => {
        let newIndex = person.index + 10;
        person.index = newIndex;
        updatePerson(person);
        retrievePeople();


        const newPeopleState = people.map((p) => {
            if (p.id === person.id) {
              p.index = person.index;
            }
            return p;
        });
        setPeople(newPeopleState);
}

【问题讨论】:

    标签: react-hooks use-state setstate


    【解决方案1】:

    我使用了我的问题中的第 4) 点并对其进行了详细说明。我知道如果只是为使用后端调用的人设置状态,React 不会调用重新渲染,因为它仍然是相同的状态。因此,为了工作,您必须创建一个新列表,它是旧列表的克隆,但会根据更新进行更改。这可以使用 map 函数并更改列表中更新项目的属性值来完成(请参阅问题中的第 4 点)。为了避免前端和后端不一致,您可以使用以下内容:

    PeopleService.update(person)
      .then(response => {
       // backend have made the update
       const newPeopleState = people.map((p) => {
           if (p.id === person.id) {
              p.index = person.index;
           }
           return p;
       });
       setPeople(newPeopleState);
       })
       .catch(e => {
             console.log(e);
       });
    

    只有在后端进行了更新时,您才能在状态中进行类似的结构更改。如果有问题,则不进行更改。

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 2020-05-14
      • 1970-01-01
      • 2012-02-07
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 2018-05-08
      相关资源
      最近更新 更多