反应钩子 useState 不使用 onSubmit 更新
Posted
技术标签:
【中文标题】反应钩子 useState 不使用 onSubmit 更新【英文标题】:React hook useState not updating with onSubmit 【发布时间】:2019-09-15 05:07:26 【问题描述】:我目前在将输入字段值推送到 onSubmit 状态时遇到问题。
codesandbox
我正在尝试将输入字段值设置为状态,以便在组件更新后可以使用该值将用户重定向到另一个页面。我手动测试了路径并且它可以工作,但是由于状态没有同步更新,重定向不起作用。我可以在页面上呈现输入值,但如果我尝试记录它,它长未定义(第一次)和第二次提交时的先前状态。
import React, useRef, useState from "react";
import db from "../firebase";
import Redirect from "@reach/router";
function CreateProject(props)
const [id, setID] = useState(null);
const colorRef = useRef(null);
const projectNameRef = useRef(null);
const handleSubmit = e =>
e.preventDefault();
const project =
name: projectNameRef.current.value,
colors: [colorRef.current.value],
colorName: colorNameRef.current.value,
createdAt: new Date()
;
setID(projectNameRef.current.value);
db.collection("users")
.doc(`$props.user`)
.collection("projects")
.doc(`$projectNameRef.current.value`)
.set( ...project );
e.target.reset();
;
return id ? (
<Redirect from="/projects/new" to=`projects/:$id` noThrow />
) : (
<div>
<div>
<h1>Create new selection</h1>
<form onSubmit=handleSubmit>
<label>Color</label>
<input ref=colorNameRef type="text" name="colorName" />
<label>Project Name</label>
<input ref=projectNameRef type="text" name="projectName" required />
<button type="submit">Submit</button>
</form>
</div>
</div>
);
export default CreateProject;
反应:16.8.6
【问题讨论】:
它是否重定向?还是新的 url 缺少正确的 id? 它正在重定向,但只是重定向到“/projects”而不是“projects/InputValue” 【参考方案1】:这就是 react 钩子 useState 的工作方式,要在状态更改后执行某些操作,您应该在 useEffect 钩子中执行它,如下所示:
useEffect(() =>
if (id)
console.log(id);
projectNameRef.current.value = ''
, [id])
每次id
值更改时(以及在第一次渲染中)都会运行此效果,因此您可以在此处添加逻辑并根据状态更改执行所需的操作。
【讨论】:
当用useState
改变状态时,react不会等待它继续,它是异步的,所以这就是为什么用useEffect
钩子监听状态变化是react的方式16.
More info about the useEffect
hook.
谢谢 :) ,在重构和添加 useEffect 之后,它运行正常,但它没有重定向到它应该重定向的位置,经过多次尝试后,我发现我在重定向中有错误,我被重定向到=projects/:$id
而不是=projects/$id
【参考方案2】:
我认为您在此处使用 ref
是不恰当的,可能会导致问题。
我会像这样重写你的函数。
function CreateProject()
const [id, setID] = useState(null);
const [shouldRedirect, setShouldRedirect] = useState(false);
const handleSubmit = e =>
e.preventDefault();
setShouldRedirect(true);
;
const handleChange = (e) =>
setID(e.target.value);
return shouldRedirect ? (
<Redirect from="/projects/new" to=`projects/:$id` noThrow />
) : (
<div>
<div>
<h1>Create new selection</h1>
<form onSubmit=handleSubmit>
<label>Project Name</label>
<input onChange=handleChange type="text" name="projectName" required />
<button type="submit">Submit</button>
</form>
</div>
</div>
);
通过这种方式,您的状态始终在更新,因此您的重定向 URL 也是如此。 提交时,您只需告诉组件现在应该使用当前 ID 提交。
You can see how this works from the React documentation.
您甚至可以使用withRouter
调用history.push
来替换条件渲染。 See advice on this question.
【讨论】:
以上是关于反应钩子 useState 不使用 onSubmit 更新的主要内容,如果未能解决你的问题,请参考以下文章