默认 prop 值的 useEffect 无限循环问题

问题描述 投票:0回答:2

我有一个下拉组件;这里的重要部分:

import { useEffect, useState } from "react"

type PropsType = {
    options?: any[]
}

export const DropDown = (props: PropsType) => {

    const { options = [] } = props;

    const [query, setQuery] = useState('');

    const [filteredOptions, setFilteredOptions] = useState([]);

    useEffect(() => {
        setFilteredOptions(()=>[]); // calculate the filtered options according to the options and query cahnges
    }, [query, options])

    return (
        <div>
            DropDown
        </div>
    )
}

如你所见,我有一个

options
属性,如果你不指定它,它将是一个空数组。

这是该组件的简单用例:

<DropDown options={[]} />

但是如果将

options
属性设置为
undefined
:

<DropDown options={undefined} />

...你会得到一个无限循环。

重要的是我知道如何使用

useRef

解决无限循环

但是使用后又会有一个问题

useRef
:

如果使用

useRef
来解决问题,如果在运行时改变
options
值,例如调用 API 后改变
options
状态,在下拉组件中,
useEffect
不会触发。

当有人将其设置为

options
时,我应该怎么做才能拥有动态
undefined
而不会无限循环?

幕后发生了什么?

import { useEffect, useState } from "react";
import { DropDown } from "./dropdown";
function App() {
  const [options,setOptions] = useState<string[]>([]);
  useEffect(()=>{
    setOptions(()=>['a','b'])
  },[])
  return (
    <div>
      <DropDown options={options}/>
    </div>
  );
}
javascript reactjs typescript react-hooks
2个回答
2
投票

我认为这里的问题是你有选项的默认值。 UseEffect 触发新渲染,在该渲染上您将获得一个新选项(因为空数组每次创建时都会有新的内存链接,并且在每次渲染上创建),该新选项数组触发 useEffect 导致新渲染并继续无限循环。

我想在理解了这一点之后,你就很容易解决这个问题了。最简单的修复方法(但我不确定)是设置 Dropdown.defaultProps,这样您就可以在那里设置选项而不是组件本身。

祝你好运!


0
投票

您可以在组件外部添加一个包含空数组的变量,并使用该变量作为默认值。

const empty = [];
const Component = ({ options = empty }) => ()
© www.soinside.com 2019 - 2024. All rights reserved.