首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >React : useEffect更新状态,但不重新呈现视图。

React : useEffect更新状态,但不重新呈现视图。
EN

Stack Overflow用户
提问于 2020-08-03 20:51:51
回答 1查看 421关注 0票数 1

我想对一组对象进行排序。但是我在这里停留了一段时间:当道具filterActivated发生变化时,状态会被更新(在浏览器的react工具中验证),但是没有重新呈现。

我不明白为什么视图不被重新呈现,即使ideasArray正在更新。

这是我的组成部分:

代码语言:javascript
运行
复制
import React, { useState, useEffect } from 'react'

// Components
import Idea from './Idea'

const IdeasContainer = ({ filterActivated }) => {

    const [ideasArray, setIdeasArray] = useState([]);

    useEffect(() => {
        const getIdeas = async () => {
            try {
                const response = await fetch("http://localhost:3004/api/ideas")
                const data = await response.json()
                setIdeasArray(data)
            } catch (err) {
                console.error('getIdeas error: ', err, err.stack)
            }
        }
        getIdeas();
    }, []);

    useEffect(() => {
        const sorted = (array) => {
            let newArray = array.sort(function (a, b) {
                if (filterActivated === 'scoreAsc') {
                    return a.score - b.score
                }
                else if (filterActivated === 'scoreDesc') {
                    return b.score - a.score
                }
            });
            setIdeasArray(newArray);
        }
        sorted(ideasArray);
    }, [filterActivated, ideasArray]);

    return (
        <div className="ideasContainer">
            {
                ideasArray.map((idea, index) => {
                    return <Idea key={index} dataIdea={idea} />
                })
            }
        </div>
    )
}

export default IdeasContainer;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-03 21:06:49

首先,您的useEffect有几个问题:

如果要在ideasArray中设置该值,则不要将该useEffect引用为useEffect依赖项。这将导致无限循环,因为当您设置值时,‘`useEffect’再次被调用,它设置值,后者再次调用它,设置值.诸若此类。如果您依赖于前面的值来设置新值,那么将一个setter函数传递给setIdeasArray函数,例如:

代码语言:javascript
运行
复制
useEffect(() => {
  setIdeasArray(oldValue =>
    [...oldValue].sort((a, b) => {
      if (filterActivated === "scoreAsc") {
        return a.score - b.score;
      } else if (filterActivated === "scoreDesc") {
        return b.score - a.score;
      }
    })
  );
}, [filterActivated]);

注意,在排序之前,我也是如何将oldValue扩展到一个新数组中的。这是因为Array.sort并不是可靠的不可变的,所以在某些情况下它会改变原始数据,我们不想在反应中这样做。

如果状态更改,则始终存在重呈现。React的呈现周期与DOM的变化不一样,但是如果支持或状态发生变化,React仍将运行组件呈现周期。

您所遇到的问题是将index用作每个想法的key。使用索引作为键是一个非常糟糕的主意。

键的全部意义是允许响应来识别数组中的项,而不必重新呈现它们,因此,通过使用索引,您实质上说的是第一个项(总是索引0)永远不会改变。是的,您的状态是重新排序的,但是React看到键没有更改顺序,所以它不会更改DOM来匹配。

键需要与项相关(例如唯一的id),这样,React就可以通过与“其在数组中的位置”无关的东西来识别该项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63236796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档