gpt4 book ai didi

javascript - 具有提升状态和受控依赖的 React 表单提交逻辑

转载 作者:行者123 更新时间:2023-11-28 03:09:12 34 4
gpt4 key购买 nike

为了尝试使用 React hooks,我用这个组件给自己挖了一个很深的兔子洞。

父组件处理最终分发到多个组件的字典状态。

我的问题子组件 WordInput 有一个带有单个输入的表单。提交表单时,组件从 API 获取单词的定义,并将单词和定义传递给父级,然后父级以字典的形式设置状态。到目前为止,如果它是字典中的第一个单词,那就太好了。我遇到麻烦的部分是提交任何后续单词/定义。

当用户提交后续单词时,我希望组件检查该单词是否已存在于传递给子项的字典中。如果不存在,请通过提交功能将其添加到字典中。

我认为问题是我试图用 useEffect 做太多事情我 useEffect 来: - 设置加载 - 检查并处理字典中现有的单词 - 检查定义和单词是否不为空并将两者提交给父/词典 - 从 API 获取定义

在未处理的代码中,我有多个 console.groups 来帮助我跟踪正在发生的情况。添加到组件中的越多,子组和子组的子组就越多。显然,我采用的方法不是很干燥,并且会导致组件/useEffect 函数的过多重新渲染。为了简洁起见,我删除了 console.log 条目。

导入的fetchWordDefinition仅处理获取的数据并将其正确排列到数组中。

我不知道如何保持干燥和有效,对于这个相当简单的任务,我们将不胜感激。我的直觉是保留提交处理程序中提交单词/定义的所有逻辑,并且仅使用 useEffect 来验证之前的数据。

import React, { useState, useEffect } from "react";
import fetchWordDefinition from "./lib/utils";

const WordInput = ({ onSubmit, dictionary }) => {
const [definition, setDefinition] = useState([]);
const [cause, setCause] = useState({ function: "" });
const [error, setError] = useState({});
const [loading, setLoading] = useState(false);
const [word, setWord] = useState("");
const [wordExistsInDB, setWordExistsInDB] = useState(false);

useEffect(() => {
const dictionaryEmpty = dictionary.length === 0 ? true : false;

if (dictionaryEmpty) {
return;
} else {
for (let i = 0; i < dictionary.length; i += 1) {
if (dictionary[i].word === word) {
setWordExistsInDB(true);
setError({ bool: true, msg: "Word already exists in DB" });
break;
} else {
setWordExistsInDB(false);
setError({ bool: false, msg: "" });
}
}
}
}, [dictionary, word]);

useEffect(() => {
const definitionNotEmpty = definition.length !== 0 ? true : false;
const wordNotEmpty = word !== "" ? true : false;

if (wordNotEmpty && definitionNotEmpty && !wordExistsInDB) {
onSubmit(word, definition);
setWord("");
setDefinition([]);
}
}, [definition, word, onSubmit, wordExistsInDB]);

useEffect(() => {
if (cause.function === "fetch") {
async function fetchFunction() {
const fetch = await fetchWordDefinition(word);
return fetch;
}

fetchFunction().then(definitionArray => {
setDefinition(definitionArray);
setCause({ function: "" });
});
}
}, [cause, word]);

const handleSubmit = async e => {
e.preventDefault();

setLoading(true);
setCause({ function: "fetch" });
};

return (
<form onSubmit={handleSubmit}>
{error.bool ? <span>{error.msg}</span> : null}
<input
name='word'
placeholder='Enter Word'
type='text'
value={word}
onChange={({ target: { value } }) => setWord(value)}
/>
<input type='submit' />
</form>
);
};

export default WordInput;

最佳答案

确实发生了不必要的 useEffect 事件以及大部分状态。您所需要的只是 handleSubmit 来进行提取。

const WordInput = ({ onSubmit, dictionary }) => {
const [word, setWord] = React.useState("");
const handleChange = React.useCallback(e => {
setWord(e.currentTarget.value)
}, [])
const handleSubmit = React.useCallback(() => {
//check if word is in dictionary
const wordIsAlreadyThere = dictionary.map(entry => entry.word).includes(word)
//fetch the definition, wait for it, and call submit
if(!wordIsAlreadyThere && word.length > 0){
fetchWordDefinition(word)
.then(definition => {
onSubmit(word, definition)
setWord('')
}).catch(err => console.log(err))
}
}, [])
return (
<form onSubmit={handleSubmit}>
<input
value={word}
onChange={handleChange}/>
<input type='submit' />
</form>
);
}

关于javascript - 具有提升状态和受控依赖的 React 表单提交逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60311586/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com