reactjs - 如何修复两个绑定需要同时更新的属性的 useEffect 无限循环?
问题描述
我有一个自动完成组件:
自动完成
function Autocomplete() {
const [ matches, setMatches ] = useState([ 'game' ]);
const [ query, setQuery ] = useState('');
const [ menuState, setMenuState ] = useState(false);
useEffect(() => {
if(query !== ""){
updateQuery()
}
}, [query])
const updateQuery = async () => {
const data = await props.searchQuery(query);
if(data.length > 1 ){
setMenuState(true);
setMatches(data);
} else if (data.length < 1){
setMenuState(false);
setMatches([]);
}
}
return (
<div className={rootClassName(null, [props.className], classStates)} style={styles}>
<div className='Autocomplete__Trigger'>
<input
className='Input'
type='text'
placeholder={props.placeholder}
value={query}
onChange={ e => setQuery(e.target.value) }
onKeyDown={ handleKeyPress }
/>
</div>
<div className='Autocomplete__Menu' role='menu'>
{
//Custom if function
If(matches.length > 0, () => (
<div className='Autocomplete__Content'>
{
//Custom loop
For(matches, (item, index) => (
//loops through matches
))
}
</div>
)).EndIf()
}
</div>
</div>
);
}
export default Autocomplete;
基本上它的工作原理如下:
- 当在输入中输入内容时,会设置一个查询字符串:
<input
onChange={ e => setQuery(e.target.value) }
/>
- 查询状态立即设置
useEffect
并updateQuery()
调用:
useEffect(() => {
//If input is empty
if(query !== ""){
updateQuery()
}
}, [query])
- 在
updateQuery()
自动完成中的所有菜单项中,都从 API 请求,并且匹配项设置为循环并指示菜单是否打开:
const updateQuery = async () => {
const data = await props.searchQuery(query);
if(data.length > 1 ){
setMenuState(true);
setMatches(data);
} else if (data.length < 1){
setMenuState(false);
setMatches([]);
}
}
我遇到的问题是匹配状态滞后,但如果我将它添加到useEffect
我会得到一个无限循环,因为updateQuery
总是被调用:
useEffect(() => {
//If input is empty
if(query !== ""){
updateQuery()
}
}, [query, matches])
我怎样才能使它如此匹配并且查询状态在没有无限循环的情况下同时更新?
解决方案
您可以将依赖代码放在 useEffect 中并调用它。这样,函数就不会在每次渲染时都重新声明。它仅在重新运行效果时更改。
这可能在某处缺少等待或异步修饰符,但要给出这个想法。
useEffect(() => {
const updateQuery = async () => {
const data = await props.searchQuery(query);
if(data.length > 1 ){
setMenuState(true);
setMatches(data);
} else if (data.length < 1){
setMenuState(false);
setMatches([]);
}
}
//If input is empty
if(query !== ""){
updateQuery()
}
}, [query])
推荐阅读
- asp.net - ASP.NET 4.6 SPA,通过 MsBuild 动态发布整个 wwwroot 内容
- javascript - Highcharts 如何将内联样式添加到 HTML 元素中?
- python - Pyinstaller 的 PyQT5 QFileDialog 问题
- javascript - 如何将加载器图像添加到在其中加载 iframe 的对话框
- laravel - Laravel spatie QueryBuilder GET 请求搜索
- php - php函数的浮动输出
- python - 对于 Postgres Django 的类型字符变化(255)SQLite3 的值太长
- forms - 根据 vueJS 表单输入上的数据道具设置规则
- mysql - 创建存储函数以检索两个日期之间的总金额
- c# - 在 Azure App Server 中使用 Hangfire 进行计算昂贵操作的替代方法