Javascript 如何在React中的功能组件中创建与componentDidUpdate函数类似的函数?
我试图为注册表设置一条错误消息,但因为我使用的是material UI,所以我必须为我的项目使用功能组件。我在youtube上看教程,但那个家伙在用一个类组件。我成功地将大多数代码转换为一个功能组件,但我在componentDidUpdate函数中迷失了方向 我还尝试使用useEffect功能,但没有用,如果有人没有输入任何字段,单击submit按钮时,我无法显示警报/消息错误。我还得到一个错误,msg没有在注册组件中的警报组件中定义,尽管它已经在useState函数中定义Javascript 如何在React中的功能组件中创建与componentDidUpdate函数类似的函数?,javascript,reactjs,use-effect,Javascript,Reactjs,Use Effect,我试图为注册表设置一条错误消息,但因为我使用的是material UI,所以我必须为我的项目使用功能组件。我在youtube上看教程,但那个家伙在用一个类组件。我成功地将大多数代码转换为一个功能组件,但我在componentDidUpdate函数中迷失了方向 我还尝试使用useEffect功能,但没有用,如果有人没有输入任何字段,单击submit按钮时,我无法显示警报/消息错误。我还得到一个错误,msg没有在注册组件中的警报组件中定义,尽管它已经在useState函数中定义 {msg ? <
{msg ? <Alert color="danger">{msg}</Alert> : null}
我创建了一个带有表单字段验证和功能组件的最小示例。 注意,您可以将任何组件编写为函数和类。我个人更喜欢函数,因为它们通常更简洁 在此处运行示例:
import React,{useState}来自“React”;
从“react dom”导入react dom;
常量应用=()=>{
const[error,setError]=useState(null);
返回(
{error&&{error}
setError(“那不是电子邮件。”)}
必修的
/>
);
};
const rootElement=document.getElementById(“根”);
render(,rootElement)
useEffect
带有空依赖项的数组将不像componentDidUpdate
一样运行,它将仅在组件首次装载时运行,而在组件重新呈现时不会运行
要模拟componentdiddupdate
,请将错误作为依赖项提供
const [errorMsg, setErrorMsg] = useState('');
useEffect(() => {
if (error.id === "REGISTER_FAIL") {
setErrorMsg(props.error.msg.msg);
}
}, [props.error])
return (
<div className="App">
{errorMsg && <span>{errorMsg}</span>}
</div>
);
const[errorMsg,setErrorMsg]=useState(“”);
useffect(()=>{
如果(error.id==“REGISTER\u FAIL”){
setErrorMsg(props.error.msg.msg);
}
},[props.error])
返回(
{errorMsg&&{errorMsg}
);
我还建议您在每次提交表单时发送一个操作,并将错误消息重置为存储中的错误值'
通过这种方式,每次提交时,您都不会看到最后一个错误
,并且当您将使用效果
视为一个在使用“副作用”(更改状态)作为组件更新
时,也不需要比较错误,您需要注意错误
和消息
状态的变化
而不是
// Similar to componentDidMount and componentDidUpdate
//By running an empty array [] as a second argument,
//we’re letting React know that the useEffect function doesn’t
//depend on any values from props or state.
useEffect(() => {
const { error } = props;
if (error !== form.error) {
//check for register error
if (error.id === "REGISTER_FAIL") {
setValues({ msg: error.msg});
} else {
setValues({ msg: null });
}
}
}, []);
你需要做什么
useEffect(() => {
const { error } = props;
if (error !== form.error) {
//check for register error
if (error.id === "REGISTER_FAIL") {
- setValues(({ msg: error.msg});
+ setValues({ ...form, msg: error.msg});
} else {
- setValues({ msg: null });
+ setValues({ ...form, msg: null });
}
}
}, [error, form.msg]);
我之所以传播…form
像setValues({…form,msg:error.msg.msg})
是因为React.useState
返回的更新程序函数(第二个参数)不会更新状态中的其他属性
SosetValues({msg:null})代码>将从
{
name: 'previous name',
password: 'previous password',
email: 'previous email',
msg: 'previous message...'
}
进入{msg:null}
删除姓名、电子邮件、密码
属性
由于React.useState
的更新程序(“别名”为setState
in)和setState
之间的行为不同,最终有人创建了它,除非绝对必要,否则您可能不应该使用它
旁注
与你的问题无关,你也可以
1.将名称/电子邮件/密码/msg
分为不同的状态
2.或“使用钩子”
案例1的实施变化
如果要继续使用对象表单
,可能需要遵循命名约定,将setValues
更改为setForm
或const[formValues,setFormValues]=useState({…})
您可以更新每个字段,如
<TextField
autoComplete="name"
name="name"
variant="outlined"
required
fullWidth
id="name"
label="Full Name"
autoFocus
value={name}
onChange={e => setName(e.target.value)}
/>
setName(e.target.value)}
/>
您可以在此处使用foronChange
如onChange={useCallback(e=>setName(e.target.value),[name])}
,但除非您有性能问题,否则不必使用。一开始很简单,这应该是一个基于类的组件,在这里使用功能组件没有意义,IMHO.Hi@TobiasTengler。我可以问一下为什么功能组件(FC)在这里不起作用吗?我想知道为什么(不是想争论,只是想了解你的思维过程我从来没有说过它不起作用,只是基于类的组件对我个人来说更有意义。一般来说,功能组件应该是哑的,只呈现通过道具提供给它们的东西。那里有一堆处理程序,OP想添加更多的处理程序通过引入生命周期挂钩来增加复杂性。我想随着最近的更新,也许我只是在这方面过时了,谁知道呢,只是个人偏好。很抱歉,我误读了你之前的消息@TobiasTengler我理解你的观点,使用类组件更好,但我仍在尝试arn钩子使功能组件具有状态。另外,据我所知,material ui不支持类组件。感谢上面的代码。我使用上面的一些代码显示了消息。谢谢。这当然是一个很大的帮助和详细的解释。我将尝试案例#1,如果有任何问题,我将与您联系鱼钩。
{
name: 'previous name',
password: 'previous password',
email: 'previous email',
msg: 'previous message...'
}
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
<TextField
autoComplete="name"
name="name"
variant="outlined"
required
fullWidth
id="name"
label="Full Name"
autoFocus
value={name}
onChange={e => setName(e.target.value)}
/>