【问题标题】:React Hook useEffect() run continuously although I pass the second params尽管我通过了第二个参数,但 React Hook useEffect() 连续运行
【发布时间】:2020-02-01 20:31:44
【问题描述】:

这段代码有问题

如果我将整个pagination 对象传递给useEffect() 函数的第二个参数,那么fetchData() 将连续调用。如果我只通过pagination.current_page,那么它只会调用一次,但是当我设置新的pagination 时,正如您在navigatePage() 函数中看到的那样,useEffect() 不会调用fetchData(),尽管pagination 已经改变。

如何解决这个问题。非常感谢!

除了我不希望在第一次安装组件时使用useEffect() 调用,因为items 是从props 接收的(它是由服务器获取的,这是nextjs 项目)。

import React, {useEffect, useState} from 'react';
import Filter from "../Filter/Filter";
import AdsListingItem from "../AdsListingItem/AdsListingItem";
import {Pagination} from "antd-mobile";

import styles from './AdsListing.module.css';

import axios from 'axios';

const locale = {
    prevText: 'Trang trước',
    nextText: 'Trang sau'
};

const AdsListing = ({items, meta}) => {

    const [data, setData] = useState(items);

    const [pagination, setPagination] = useState(meta);

    const {last_page, current_page} = pagination;

    const fetchData = async (params = {}) => {
        axios.get('/ads', {...params})
            .then(({data}) => {
                setData(data.data);
                setPagination(data.meta);
            })
            .catch(error => console.log(error))
    };

    useEffect( () => {
        fetchData({page: pagination.current_page});
    }, [pagination.current_page]);

    const navigatePage = (pager) => {
        const newPagination = pagination;
        newPagination.current_page = pager;
        setPagination(newPagination);
    };

    return (
        <>
            <Filter/>
            <div className="row  no-gutters">
                <div className="col-md-8">
                    <div>
                        {data.map(item => (
                            <AdsListingItem key={item.id} item={item}/>
                        ))}
                    </div>
                    <div className={styles.pagination__container}>
                        <Pagination onChange={navigatePage} total={last_page} current={current_page} locale={locale}/>
                    </div>
                </div>
                <div className="col-md-4" style={{padding: '15px'}}>
                    <img style={{width: '100%'}} src="https://tpc.googlesyndication.com/simgad/10559698493288182074"
                         alt="ads"/>
                </div>
            </div>


        </>
    )
};

export default AdsListing;

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    问题是您没有返回 new 对象引用。你保存对最后一个状态对象的引用,改变它的属性,然后再次保存。

    const navigatePage = (pager) => {
      const newPagination = pagination; // copy ref pointing to pagination
      newPagination.current_page = pager; // mutate property on ref
      setPagination(newPagination); // save ref still pointing to pagination
    };
    

    在这种情况下,是 pagination 在内存中的位置保持不变。您应该将所有pagination 属性复制到一个新对象中。

    const navigatePage = (pager) => {
      const newPagination = {...pagination}; // shallow copy into new object
      newPagination.current_page = pager;
      setPagination(newPagination); // save new object
    };
    

    为了更进一步,您确实应该进行功能更新,以便正确排队更新。这是在单个渲染周期内多次调用setPagination 的情况。

    const navigatePage = (pager) => {
      setPagination(prevPagination => {
        const newPagination = {...prevPagination};
        newPagination.current_page = pager;
      });
    };
    

    在分页队列更新的情况下可能不是问题(最后一个当前页面集赢得下一次渲染战斗),但如果有任何状态更新实际上取决于以前的值那么肯定使用功能更新模式,

    【讨论】:

      猜你喜欢
      • 2019-04-14
      • 2021-04-02
      • 2020-02-21
      • 2020-06-19
      • 2021-01-28
      • 2020-05-17
      • 2021-03-15
      • 2019-08-09
      • 2020-01-07
      相关资源
      最近更新 更多