React hook useState 未随 onSubmit 更新
React hook useState not updating with onSubmit
我目前在将输入字段值推送到状态 onSubmit 时遇到问题。
我正在尝试将输入字段值设置为状态,以便在组件更新后我可以使用该值将用户重定向到另一个页面。我手动测试了路径并且它有效,但由于状态没有同步更新,重定向不起作用。我可以在页面上呈现输入值,但如果我尝试记录它,它很长未定义(第一次)并且在第二次提交时是以前的状态。
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
这就是反应钩子 useState 的工作方式,要在状态更改后执行某些操作,您应该在 useEffect 钩子中执行它,例如以下:
useEffect(() => {
if (id) {
console.log(id);
projectNameRef.current.value = ''
}
}, [id])
每次 id
值更改时(以及在第一次渲染中),此效果都会 运行,因此您可以在那里添加逻辑并根据状态更改执行所需的操作。
我认为您在这里使用 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
的函数调用。
我目前在将输入字段值推送到状态 onSubmit 时遇到问题。
我正在尝试将输入字段值设置为状态,以便在组件更新后我可以使用该值将用户重定向到另一个页面。我手动测试了路径并且它有效,但由于状态没有同步更新,重定向不起作用。我可以在页面上呈现输入值,但如果我尝试记录它,它很长未定义(第一次)并且在第二次提交时是以前的状态。
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
这就是反应钩子 useState 的工作方式,要在状态更改后执行某些操作,您应该在 useEffect 钩子中执行它,例如以下:
useEffect(() => {
if (id) {
console.log(id);
projectNameRef.current.value = ''
}
}, [id])
每次 id
值更改时(以及在第一次渲染中),此效果都会 运行,因此您可以在那里添加逻辑并根据状态更改执行所需的操作。
我认为您在这里使用 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
的函数调用。