【问题标题】:React state not updating after filtering the data过滤数据后反应状态不更新
【发布时间】:2021-07-06 07:46:40
【问题描述】:

我正在制作一个应用程序,它应该使用下拉列表按标签过滤图像。我最初将我的图像设置为状态,并通过它们进行映射以显示它们。还有一个下拉列表,显示用户可以从中过滤的标签列表。在更改选择框时,我正在重置状态以拥有所有图像,然后过滤图像,然后再次设置状态以反映新的过滤图像列表。我遇到的问题是,当我最初选择一个过滤器时,它会根据它们的标签向我显示正确的图像,但是当我尝试选择另一个过滤器时,它会将我的状态设置为一个空数组,即使我将状态重置为它是原始状态。这是我正在使用的当前文件:


// Dependencies
import { getTags, getAllImages } from '../../utils/API';
import styled from 'styled-components';

// Components
import EachImageComponent from '../sub-components/Images/EachImageComponent';
import TagsComponent from '../sub-components/TagsComponent';

const GalleryComponent = () => {
    //Set state
    const [allImages, setAllImages] = useState([]);
    const [images, setImages] = useState([]);
    const [tags, setTags] = useState([]);
 
    //On first mount, get all the images and tags, and set them in state. 
    useEffect( async () => {
        const response = await getAllImages();

        if(!response) {
            throw new Error('No images to display!')
        }
        
        let data = await response.json();
        setImages(data);
        //Using setAllImages in order to reset state to all images for later use.
        setAllImages(data);

        try {
            // Get all tags and parse them and save them to state for use in the select form
            const response = await getTags();

            if(!response.ok) {
                throw new Error('No tags found!');
            }

            const tags = await response.json();
            tags.unshift({tagName: "All"});

            setTags(tags);
        } catch (err) {
            console.log(err)
        }
        
    }, []);

    const handleSelectChange = async (e) => {
        // Set the current tag that has been selected in varaibale
        let tag = e.target.value;
        // If selected tag has a value of 'All', then images state to all images for display
        if(tag === 'All') {
            const response = await getAllImages();

            if(!response) {
                throw new Error('No images to display!')
            }
            
            let data = await response.json();
            setImages(data)
        } else {
            // If the selected tag is not 'All' reset state to allImages, then filter the images 
             by tag, then set images to the filtered images
            setImages(allImages)
            let newImages = images.filter(image => image.tags.tagName === tag)
            setImages(newImages)
        }
    }

    return (
        <>
             <select onChange={handleSelectChange} name="tagsIndex" id="tag">
                {tags.map(tag => (<TagsComponent tag={tag} key={tag._id} />))}
            </select>
            <StyledDiv>
                { images.map(image => (<EachImageComponent image={image} key={images._id} />)) }
            </StyledDiv>
        </>
    )

}

我不确定我是否在此处错误地使用了状态,但我似乎无法让我的状态恢复到原来的形式。我很确定这正在发生,因为在第二次尝试时,它正在尝试过滤和已经过滤的数组,而这又将返回一个空数组,但我不确定为什么当我运行 setImages 时状态会被重置(allImages) 在我再次过滤之前。如果这有帮助,这里是image of data I am getting for Images

【问题讨论】:

  • setImages() 函数不会立即更改状态。您可以将所选标签存储在 state 中,并根据该标签显示过滤结果,而不是根据其他状态设置状态。如果计算值可能很昂贵,您可以使用useMemo() 挂钩来记忆结果。

标签: reactjs react-hooks state


【解决方案1】:

您不必每次在下拉列表中选择值时都更改数组,而是必须像这样渲染图像:

{images.filter(image => image.tags.tagName === tag).map(image => (<EachImageComponent.../>))}

这样你不必每次更改标签时都获取图像,并且它也可以按预期工作

【讨论】:

    猜你喜欢
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2021-05-01
    • 2020-01-13
    • 2020-03-29
    • 2021-03-31
    • 2018-03-28
    相关资源
    最近更新 更多