使用 useEffect 钩子在反应功能组件中未使用 .map() 显示的元素

Posted

技术标签:

【中文标题】使用 useEffect 钩子在反应功能组件中未使用 .map() 显示的元素【英文标题】:Elements not displaying with .map() in react functional component with useEffect hook 【发布时间】:2020-10-02 12:59:59 【问题描述】:

我在 useEffect 回调中创建了一个类别数组,当我 console.log 时它工作正常。

但是当我 .map() 它时,结果数组是空的。

import React,  useEffect  from 'react';

export const Categories = (props) => 
    let categories = [];

    useEffect(() => 
        props.films.forEach((film) => 
            if (categories.findIndex(item => item === film.category) === -1)
            
                categories.push(film.category);
                console.log(categories);
            

        )
    , [props.films, categories])

    return (
        <div>
            categories.map((category) => 
                return (
                    <div>
                        category
                    </div>
                )
            )
        </div>
    );

有人有想法吗?

【问题讨论】:

【参考方案1】:

您应该为类别使用状态值:

const [categories, setCategories] = React.useState([])

useEffect(() => 
    let categories = []
    props.films.forEach((film) => 
        if (categories.findIndex(item => item === film.category) === -1)
        
            categories.push(film.category);
            console.log(categories);
        

    )
    setCategories(categories)
, [props.films])

【讨论】:

【参考方案2】:

categories 中的数据发生更改时,组件不会重新呈现。为了呈现categories,您需要使用useState 存储数据。

import React,  useEffect, useState  from 'react';

export const Categories = (props) => 
    const [categories, setCategories] = useState([]);

    useEffect(() => 
        let filmCategories = []
        props.films.forEach((film) => 
            if (categories.findIndex(item => item === film.category) === -1)
            
                filmCategories.push(film.category);
                console.log(filmCategories);
            
        )
        setCategories(filmCategories)
    , [props.films])

    return (
        <div>
            categories.map((category) => 
                return (
                    <div>
                        category
                    </div>
                )
            )
        </div>
    );

希望这会有所帮助。

【讨论】:

【参考方案3】:

我想你可能是新手。我建议你看看React State and Lifecycle

您正在使用 react 钩子 useEfect,它将在您的组件在 DOM 中呈现后调用

我可以想到两种可能的解决方案来解决这个问题

1) 使用反应钩子useState

import React,  useEffect  from 'react';

export const Categories = (props) => 
    //Make the local variable into a variable representing state
    let [categories, setCategories] = useState([]);

    useEffect(() => 
        const result = [...categories];
        props.films.forEach((film) => 
            if (result.findIndex(item => item === film.category) === -1)
            
                result.push(film.category);
                console.log(result);
            

        )
        //Set the state value to trigger a re-render of your component
        if(result.length !== categories.length)
            setCategories(result);
    , [props.films, categories])

    return (
        <div>
            categories.map((category) => 
                return (
                    <div>
                        category
                    </div>
                )
            )
        </div>
    );

2) 如果不需要重新渲染,请移除 useEffect 钩子

import React,  useEffect  from 'react';

export const Categories = (props) => 
    let categories = props.films.map(film => 
            if (categories.findIndex(item => item === film.category) === -1)
            
                categories.push(film.category);
                console.log(categories);
            
     


    return (
        <div>
            categories.map((category) => 
                return (
                    <div>
                        category
                    </div>
                )
            )
        </div>
    );

如果需要useEffect react hook,那么方案1更好

如果不需要重新渲染react组件,那么方案2更好

【讨论】:

以上是关于使用 useEffect 钩子在反应功能组件中未使用 .map() 显示的元素的主要内容,如果未能解决你的问题,请参考以下文章

无效的挂钩调用。钩子只能在反应函数组件内部使用...... useEffect,redux

反应钩子中的prevstate

在 HoC 中使用反应钩子时的警告

如何将 React 钩子(useContext、useEffect)与 Apollo 反应钩子(useQuery)结合起来

反应:仅将主体类添加到 useEffect 挂钩中的某些组件?

使用上下文和钩子更新未安装组件的状态 - 反应原生