状态不使用React的状态挂钩更新?
我将图像发布到我的Cloudinary帐户中,并希望从imageurl
状态中的响应中保存URL。当控制台记录响应URL时,它会正确显示云URL,但setImageUrl
似乎无法正常工作。
出于安全原因,我将云详细信息更改为“虚构”
import React, { useState } from "react";
import "./image.css";
function Image() {
const [image, setImage] = useState("");
const [imageUrl, setImageUrl] = useState("");
const postDetails = async () => {
const data = new FormData();
data.append("file", image);
data.append("upload_preset", "dummy");
data.append("cloud_name", "dummy");
const settings = { method: "POST", body: data };
try {
const fetchData = await fetch(
"https://api.cloudinary.com/v1_1/dummy/image/upload",
settings
);
const resData = await fetchData.json();
console.log(resData.url);
if (resData) {
setImageUrl(resData.url);
console.log("imageUrl", imageUrl);
}
} catch (e) {
console.log(e);
}
};
return (
<>
<div className="file-field input-field">
<div className="btn #64b5f6 blue darken-1">
<span>Uplaod Image</span>
<input type="file" onChange={(e) => setImage(e.target.files[0])} />
</div>
<div className="file-path-wrapper">
<input className="file-path validate" type="text" />
</div>
</div>
<button
className="btn waves-effect waves-light #64b5f6 blue darken-1"
onClick={() => postDetails()}
>
Submit post
</button>
</>
);
}
export default Image;
I am posting an image to my Cloudinary account and want to save the URL from the response in the imageUrl
state. When console logging the response URL, it shows me the Cloudinary URL correctly but the setImageUrl
doesn't seem to be working.
I have changed my Cloudinary details to 'dummy' for security reasons
import React, { useState } from "react";
import "./image.css";
function Image() {
const [image, setImage] = useState("");
const [imageUrl, setImageUrl] = useState("");
const postDetails = async () => {
const data = new FormData();
data.append("file", image);
data.append("upload_preset", "dummy");
data.append("cloud_name", "dummy");
const settings = { method: "POST", body: data };
try {
const fetchData = await fetch(
"https://api.cloudinary.com/v1_1/dummy/image/upload",
settings
);
const resData = await fetchData.json();
console.log(resData.url);
if (resData) {
setImageUrl(resData.url);
console.log("imageUrl", imageUrl);
}
} catch (e) {
console.log(e);
}
};
return (
<>
<div className="file-field input-field">
<div className="btn #64b5f6 blue darken-1">
<span>Uplaod Image</span>
<input type="file" onChange={(e) => setImage(e.target.files[0])} />
</div>
<div className="file-path-wrapper">
<input className="file-path validate" type="text" />
</div>
</div>
<button
className="btn waves-effect waves-light #64b5f6 blue darken-1"
onClick={() => postDetails()}
>
Submit post
</button>
</>
);
}
export default Image;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为总体而言,逻辑没有错。
检查
是否(resdata)
确实是true
值。您可以这样做,以便更确定值
! resdata
或boolean(resdata)
,但请记住,空对象或空数组将是一个真实的值。如果
中没有错误尝试catch
语句,而restdata是一个真实的值,则没有机会setimageurl()
无法正常工作。I see that in general there is nothing wrong with the logic.
Check if
if (resData)
is really atrue
value.You can do it like that to be more sure about the value
!! resdata
orBoolean (resData)
, but keep in mind that an empty object or an empty array will be a truthy value.If there is no error in
try catch
statement, and restData is a truthy value there is no chance thatsetImageUrl ()
will not be working.状态更新发生异步,因此,当您调用
setImageUrl
状态更新机函数时,状态不会立即更新,首先是整个PostDetails
函数运行,然后将进行重新渲染(这意味着您的功能组件再次调用),这次usestate
挂钩将返回image> imageurl
state的更新值。因此,您的逻辑是正确的,在下一个渲染中,您将获得可在JSX中使用的更新值,但是您期望日志将在状态更新之后立即打印更新的状态是错误的。
另外,从附带说明,您无需创建一个新功能即可将其传递到
onclick
之类的:onclick = {()=&gt; postdetails()}
,您可以简单地传递postdetails
这样的函数:onclick = {postdetails}
,因为您不想将任何参数传递给该参数功能,因此创建新功能是不必要的。State update happens asynchronously, so when you call the
setImageUrl
state updater function, the state doesn't get updated immediately, first the entirepostDetails
function runs and then a re-render would take place (meaning your functional component gets called again) and this time theuseState
hook will return the updated value for theimageUrl
state.So your logic is correct, in the next render you would get the updated value which you can use in your JSX, but your expectation that the log would print the updated state immediately after the state updater is called is wrong.
Also, on a side note, you don't need to create a new function to pass it to
onClick
like this:onClick={() => postDetails()}
, you can simply pass thepostDetails
function like this:onClick={postDetails}
because you don't want to pass any arguments to the function, so creating a new function is unnecessary.