Javascript 为什么useState钩子没有保存变量的值?
我有一个简单的表单,其中包含一个模式,用于使用文本框中键入的值更新我的redux存储 我正在尝试使用useState钩子设置文本框的值。当打印到控制台时,我可以看到变量“note”的值是正确的值。但是,当尝试提交“note”并将其传递到updateCheckpoint函数时,该值未定义 此外,在打开对话框并再次提交时,注释具有正确的值Javascript 为什么useState钩子没有保存变量的值?,javascript,reactjs,react-redux,material-ui,react-hooks,Javascript,Reactjs,React Redux,Material Ui,React Hooks,我有一个简单的表单,其中包含一个模式,用于使用文本框中键入的值更新我的redux存储 我正在尝试使用useState钩子设置文本框的值。当打印到控制台时,我可以看到变量“note”的值是正确的值。但是,当尝试提交“note”并将其传递到updateCheckpoint函数时,该值未定义 此外,在打开对话框并再次提交时,注释具有正确的值 function CompetencyCheckpoint(props) { const dispatch = useDispatch(); le
function CompetencyCheckpoint(props)
{
const dispatch = useDispatch();
let [note, setNote] = useState();
function updateCheckpoint(note){
if(note != null){
console.log("Here is our note : " + note);
}else{
console.log("oh no, we didn't get the note");
}
}
console.log(note);
return (
<div className="checkpoint-container">
<i className="material-icons" onClick={()=>
dispatch(openDialog({
children: (
<React.Fragment>
<DialogTitle id="form-dialog-title">Add Note</DialogTitle>
<DialogContent>
<DialogContentText>
Enter a note.
</DialogContentText>
<TextField
id="filled-textarea"
label="New Note"
placeholder="Enter note here"
multiline
value={note}
onChange={(e) => setNote(e.target.value)}
margin="normal"
variant="filled"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={()=> dispatch(closeDialog())} color="primary">
Cancel
</Button>
<Button onClick={() => updateCheckpoint(note)} color="primary">
Add
</Button>
</DialogActions>
</React.Fragment>
)
}))}>
note_add
</i>
</div>);
}
export default (CompetencyCheckpoint);
功能能力检查点(道具)
{
const dispatch=usedpatch();
让[note,setNote]=useState();
函数updateCheckpoint(注意){
如果(注意!=null){
log(“这是我们的注释:“+note”);
}否则{
log(“哦,不,我们没有收到通知”);
}
}
控制台日志(注);
返回(
调度(openDialog)({
儿童:(
添加注释
输入注释。
setNote(e.target.value)}
margin=“正常”
variant=“filled”
全宽
/>
dispatch(closeDialog())}color=“primary”>
取消
updateCheckpoint(注意)}color=“primary”>
添加
)
}))}>
注
);
}
导出默认值(CompetencyCheckpoint);
问题在于,对话框内容的JSX是在打开对话框时捕获的,并且不会随着更改注释
状态而重新呈现而更新。这就是@AhmadNoor的解决方案导致更多问题的原因——它将TextField
从非受控更改为受控,但从未收到更新的note
值
您的openDialog
函数应该只控制对话框上的open
属性CompetencyCheckpoint
应更改为直接包含整个对话框的JSX,而不是作为openDialog
分派的参数,以便由于注释
状态的更改而将其包含在重新渲染中
下面是一种可行的方法(在我的示例中,我假设这些是重要的UI组件):
从“React”导入React;
进口{
对话
对话标题,
对话内容,
对话内容文本,
对话行动,
按钮
文本字段
}来自“@材料界面/核心”;
功能能力检查点(道具){
const[open,setOpen]=React.useState(false);
const[note,setNote]=React.useState(“”);
函数updateCheckpoint(注意){
如果(注意!=null){
log(“这是我们的注释:“+note”);
}否则{
log(“哦,不,我们没有收到通知”);
}
}
控制台日志(注);
返回(
setOpen(true)}>
注
setOpen(false)}>
添加注释
输入注释。
setNote(e.target.value)}
margin=“正常”
variant=“filled”
全宽
/>
setOpen(false)}color=“primary”>
取消
updateCheckpoint(注意)}color=“primary”>
添加
);
}
导出默认能力检查点;
我能够让代码按预期工作。我不确定,也许这与我使用儿童的方式有关:关键字,我会检查文档,看看它到底在做什么。我在遵循一个我不完全理解的先例 这是我想出的解决办法。基本上,我只是添加了一个状态变量来控制对话框是否显示天气。我想这也简化了它,所以我不会调用redux来处理对话框切换 通过使对话框成为自己的组件,可能还有进一步的重构空间
谢谢所有帮忙的人,特别是T.J和Ryan (旁注:您不需要将
note
传递给您的updateCheckpoint
函数,它会关闭它。)感谢t.J.稍微清理了一下代码:)请更新您的问题,将上述问题简化为演示问题,最好是使用堆栈片段([]
工具栏按钮)运行的问题。堆栈代码段支持React,包括JSX和钩子;——一定要阅读答案中关于钩子和如何更新React版本的部分(因为它在下拉列表中不可用)。听起来不错,我会这样做并更新。再次感谢!(ReupdateCheckpoint
-不用担心,但根据其内容的不同,可能值得将其移出组件并向其传递note
)哦,天哪,我刚刚得出了相同的结论。这确实帮助我理解了为什么状态变量没有被更新。谢谢你,瑞安!
import React from "react";
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
Button,
TextField
} from "@material-ui/core";
function CompetencyCheckpoint(props) {
const [open, setOpen] = React.useState(false);
const [note, setNote] = React.useState("");
function updateCheckpoint(note) {
if (note != null) {
console.log("Here is our note : " + note);
} else {
console.log("oh no, we didn't get the note");
}
}
console.log(note);
return (
<div className="checkpoint-container">
<i className="material-icons" onClick={() => setOpen(true)}>
note_add
</i>
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle id="form-dialog-title">Add Note</DialogTitle>
<DialogContent>
<DialogContentText>Enter a note.</DialogContentText>
<TextField
id="filled-textarea"
label="New Note"
placeholder="Enter note here"
multiline
value={note}
onChange={e => setNote(e.target.value)}
margin="normal"
variant="filled"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} color="primary">
Cancel
</Button>
<Button onClick={() => updateCheckpoint(note)} color="primary">
Add
</Button>
</DialogActions>
</Dialog>
</div>
);
}
export default CompetencyCheckpoint;