在挂钩中使用React时useEffect进入无限循环

时间:2019-09-06 21:37:06

标签: reactjs react-hooks

我正在与之分页。这样做时,我在这里将状态转移到父组件中。我使用新数组将信息转移到另一个状态,但是当我使用useEffect进行操作时,它会进入无限循环。我无法设置Dene状态。

const Pagination = ({ posts }) => {


    const gecici = posts
    const sabit = 5;

    const [dene, setDene] = useState([])
    const [degisken, setDegisken] = useState(0)



    useEffect(() => {

        degistir()

        console.log(dene)

    }, [dene])


    const degistir =() => {
        var i = 1,
            j;
        if (sabit <= gecici.length) {
            for (j = 0; j < (gecici.length / sabit); j++) {
                setDene([
                    {
                        id: i, include:
                            gecici.slice(degisken, degisken + sabit)

                    }
                ]);
                i += 1;
                setDegisken(degisken+sabit)
            }
        }
    }

自从我进行分页以来,我在每个页面上添加的内容最多达到“ sabit”值。 i表示此处的页码。

j的值是将数组填满至页面总数。

1 个答案:

答案 0 :(得分:0)

useEffect依赖项数组的工作方式是检查前一次渲染和新渲染中的数组中所有项目之间的严格(===)等价性。因此,将数组放入您的useEffect依赖项数组非常麻烦,因为与===进行数组比较会根据引用而不是内容来检查等价性。

const foo = [1, 2, 3];
const bar = foo;
foo === bar; // true

const foo = [1, 2, 3];
const bar = [1, 2, 3];
foo === bar; // false

因此,由于您拥有以下内容:

    useEffect(() => {

        degistir()

        console.log(dene)

    }, [dene])

您的组件进入无限循环。 degistir()dene的值更新为新数组。但是,即使内容相同,dene reference 也已更改,并且useEffect回调再次触发,这是无限的。

解决方案在某种程度上取决于您希望发生的确切行为。如果希望useEffect回调每次在数组的 size 更改时触发,则只需在依赖项数组中使用数组的长度,而不是数组本身即可:

    useEffect(() => {

        degistir()

        console.log(dene)

    }, [dene.length])

不太理想的解决方案是将数组转换为字符串,然后将旧的字符串化数组与新的字符串化数组进行比较:

    useEffect(() => {

        degistir()

        console.log(dene)

    }, [JSON.stringify(dene)])

这效率极低,但是如果数组中的项目数很少,则可能会起作用。

最好的选择可能是完全摆脱useEffect。您实际上不太可能需要它。取而代之的是,您可能仅通过以下操作即可完成分页:1)帖子总数,以及2)当前页面。然后只需为当前页面呈现正确的帖子,并具有一种更新当前页面值的机制即可。

也许是这样吗?因为我只会说英语,所以变量的命名让我感到困惑:

const Pagination = ({ posts }) => {


    const gecici = posts
    const sabit = 5;

    const [degisken, setDegisken] = useState(0)

    let dene = [];

        var i = 1,
            j;
        if (sabit <= gecici.length) {
            for (j = 0; j < (gecici.length / sabit); j++) {
                dene = [
                    {
                        id: i, include:
                            gecici.slice(degisken, degisken + sabit)

                    }
                ];
                i += 1;
            }
        }