React表单首次提交时date字段缺失问题求助
问题根源:React setState的异步特性
这问题我太熟了!核心原因就是React的setState是异步操作——你调用this.setState({ date: currentDate })之后,state并不会立刻更新。所以当你紧接着执行this.props.addItem(this.state)时,拿到的还是更新前的state(也就是首次提交时初始的date: "")。
至于为什么后续提交看起来正常?那是个巧合:你在提交完成后只清空了content、author、image这三个字段的state,没清空date。所以第二次提交时,this.state.date里还存着第一次提交的日期值,哪怕setState的异步更新还没完成,传给addItem的也不是空字符串,看起来就“正常”了,但其实这时候的date也不是你刚生成的最新值(只是你可能没注意到这个细节)。
两种可行的解决方案
方案一:直接构造完整的item(推荐)
既然你不需要在表单里显示日期,完全没必要把date存到Form组件的state里。直接把生成的currentDate和表单的state合并成完整的item,传给addItem就行:
handleSubmit = event => { event.preventDefault(); let myTime = function() { let today = new Date(); let hh = today.getHours(); let mn = today.getMinutes(); let dd = today.getDate(); let mm = today.getMonth() + 1; //January is 0 let yyyy = today.getFullYear(); if (dd < 10) { dd = "0" + dd; } if (mm < 10) { mm = "0" + mm; } return hh + ":" + mn + " - " + mm + "/" + dd + "/" + yyyy; }; let currentDate = myTime(); // 直接构造包含date的新item const newItem = { ...this.state, date: currentDate }; this.props.addItem(newItem); console.log(newItem); // 这里能看到正确的date this.setState({ content: "", author: "", image: "" }); };
方案二:用setState的回调函数
如果你一定要把date存到Form的state里,那就利用setState的第二个参数(回调函数)——这个函数会在state更新完成后执行,确保你拿到的是最新的state:
handleSubmit = event => { event.preventDefault(); let myTime = function() { let today = new Date(); let hh = today.getHours(); let mn = today.getMinutes(); let dd = today.getDate(); let mm = today.getMonth() + 1; //January is 0 let yyyy = today.getFullYear(); if (dd < 10) { dd = "0" + dd; } if (mm < 10) { mm = "0" + mm; } return hh + ":" + mn + " - " + mm + "/" + dd + "/" + yyyy; }; let currentDate = myTime(); // 用回调确保state更新后再调用addItem this.setState({ date: currentDate }, () => { this.props.addItem(this.state); console.log(this.state); // 这里的state已经包含最新的date了 this.setState({ content: "", author: "", image: "" }); }); };
另外还有个小优化建议:可以把myTime函数提到handleSubmit外面,避免每次提交都重新创建这个函数,能稍微提升一点性能~
内容的提问来源于stack exchange,提问作者biscarrosse
相关产品推荐
相关产品推荐

