我有一个带有模式的简单表单,该模式用于使用文本框中键入的值来更新我的redux存储。
我正在尝试使用useState挂钩来设置更改时文本框的值。当打印到控制台时,我可以看到我的变量“ 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);
答案 0 :(得分:2)
问题在于,对话框内容的JSX在打开对话框时被捕获,并且由于更改note
状态而发生重新渲染,因此不会更新。这就是@AhmadNoor的解决方案会导致更多问题的原因-它将您的TextField
从不受控制的状态更改为受控制的,但从未收到更新的note
值。
您的openDialog
函数应仅控制对话框上的open
属性。 CompetencyCheckpoint
应该更改为直接包含整个Dialog的JSX,而不是作为openDialog
调度的参数,因此由于note
状态的更改,它被包含在重新渲染中
这是一种可行的方法(在我的示例中,我假设它们是Material-UI组件):
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;
答案 1 :(得分:0)
我能够使代码按预期工作。我不确定,也许这与我使用children:关键字的方式有关,我将检查文档以查看其确切作用。我遵循的是我不完全了解的先例。
这是我想出的解决方案。基本上我只是添加了一个状态变量来控制天气,否则对话框不应该显示。我想这也简化了它,所以我不调用redux来处理对话框切换。
https://codesandbox.io/embed/focused-allen-cg1lq?fontsize=14
通过使Dialog成为其自己的组件,可能还有更多的重构空间。
谢谢大家的帮助,尤其是T.J和Ryan!