Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么useState钩子没有保存变量的值?_Javascript_Reactjs_React Redux_Material Ui_React Hooks - Fatal编程技术网

Javascript 为什么useState钩子没有保存变量的值?

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

我有一个简单的表单,其中包含一个模式,用于使用文本框中键入的值更新我的redux存储

我正在尝试使用useState钩子设置文本框的值。当打印到控制台时,我可以看到变量“note”的值是正确的值。但是,当尝试提交“note”并将其传递到updateCheckpoint函数时,该值未定义

此外,在打开对话框并再次提交时,注释具有正确的值

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版本的部分(因为它在下拉列表中不可用)。听起来不错,我会这样做并更新。再次感谢!(Re
updateCheckpoint
-不用担心,但根据其内容的不同,可能值得将其移出组件并向其传递
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;