繁体   English   中英

React:useEffect 更新了 state,但没有重新渲染视图

[英]React : useEffect updates the state, but does not re-render the view

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

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

这是我的组件:

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;

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

如果您在 useEffect 中设置该值,请不要将 ideasArray 引用为useEffect依赖useEffect 这将导致无限循环,因为当您设置值时,将再次调用 `useEffect,它设置值,再次调用它,设置值......等等。 如果您依赖于先前的值来设置新值,请将 setter function 传递给 setIdeasArray function,例如:

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 中是我们不希望发生的。


如果 state 改变,总会有一个重新渲染。 React 的渲染周期与 DOM 变化不同,但如果 props 或 state 发生变化,React 仍会运行组件渲染周期。

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

keys 的全部意义在于允许 React 识别数组中的项目而无需重新渲染它们,因此通过使用索引,您实际上是在说第一个项目(始终为索引0 )永远不会改变。 是的,你的 state 被重新排序,但 React 发现键没有改变顺序,所以它不会改变 DOM 来匹配。

键需要与项目相关(例如唯一 ID),以便 React 可以通过与“数组中的 position”无关的东西来识别该项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM