如何在下一个 useState 中访问一个 useState 的数据
How can i access the data from one useState in the next useState
我正在尝试为将使用 stripe Checkout 的项目创建一个小型市场网站。我一直在学习教程,但它没有涵盖使用来自 API 的产品。这就是我卡住的地方。
所以首先我的 table 在包含产品的 api 中有这些字段:oid |上市标题 |项目描述 |类别选择 |图片选择 |用户邮箱 |用户电话号码
这一切都完美无缺,但有一点不同。在产品 useState 中,我试图使用数据库中的这些字段来存储名称描述和价格,然后将其发送到 stripe itsel。但是,当在 itemDescription 中发送付款时,它会在名称等方面显示相同的“未定义”。除了价格,因为我将其设置为 80 只是为了测试。
现在我的问题是如何使用产品 useState 中的信息访问 api 中的字段 我的整个代码如下:
function Item({match}) {
useEffect(() => {
fetchItem();
console.log(match)
},[]);
const [item, setItem]= useState([]);
const fetchItem= async ()=>{
const fetchItem= await fetch (`http://link //?oid=${match.params.oid}`
);
const item= await fetchItem.json();
setItem(item.rows[0])
console.log(item)
}
toast.configure()
const [product] = useState({
name: item.listingTitle,
price: "80",
description: item.itemDescription,
});
console.log(product.name)
async function handleToken(token, addresses) {
const response = await axios.post(
"http://localhost:8080/checkout",
{ token, product }
);
console.log(response.status)
if (response.status === 200) {
toast("Success! Check email for details", { type: "success" });
} else {
toast("Something went wrong", { type: "error" });
}
}
return (
<div className="App">
<div className="container">
<h1 key={item.oid}></h1>
<br />
<br />
<h1 className="text-center">Stripe Checkout</h1>
<br />
<h2 className="text-center">Product Info:</h2>
<h3 className="text-center">Product Name: {item.listingTitle}</h3>
<h3 className="text-center">Product Price: {item.itemPrice}</h3>
<img className="image" src={[item.imageSelection]}width={250} height={150}></img>
<h3 className="text-center">
Product Description: {item.itemDescription}
</h3>
<br />
<div className="form-group container">
<StripeCheckout
className="center"
stripeKey=""
token={handleToken}
amount={item.itemPrice * 100}
name={item.listingTitle}
billingAddress
shippingAddress
/>
</div>
</div>
</div>
);
}
这是每个 React 新手都面临的常见问题,这里的问题是 setState 函数不会立即更新值,而是将其提交给 React 核心系统,然后在所有代码执行后分配给该状态,所以如果您 console.log 设置后下一行的状态,您将获得旧值或未定义
这就是为什么 useEffect 钩子在这里提供帮助
要跟踪一个状态并在其他状态下使用它的值,您必须像这样使用 useEffect 挂钩,例如:useEffect(()=>{},[stateToTrack])
这里我也写了一个沙盒demo大家可以看看玩
希望这会有所帮助
demo
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [item, setItem] = useState([]);
function fetchItem() {
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((r) => r.json())
.then((r) => {
setItem(r);
});
}
const [product, setProduct] = useState({
name: "",
desc: ""
});
useEffect(fetchItem, []); // run once
useEffect(() => {
// tracking item state
setProduct({
name: item.title,
desc: item.body
});
console.log(item);
}, [item]);
return (
<>
<div style={{ fontSize: 20, fontWeight: "bold" }}>{product.name}</div>
<br />
<div>{product.desc}</div>
</>
);
}
有点Javascript的基本特征;如果您不知道它是什么,那么去学习它非常重要。本质上它在它的本地环境中“包装”了一个函数并让它 运行 somewhat-independently - 对于最简单的例子,(() => {fetchItem()})
只是 returns 一个匿名函数 运行 ; (() => {fetchItem()})();
创建它并 运行 保存它。
你还有其他问题,所以可能更接近这个(假设你只想 运行 toast.configure() 一次)
function Item({match}) {
const [item, setItem]= useState([]);
const [product, setProduct] = useState({
name: item.listingTitle,
price: "80",
description: item.itemDescription,
});
useEffect(() => {
toast.configure()
(async () => {
const fetchItem= await fetch (`http://link //?oid=${match.params.oid}`);
const item= await fetchItem.json();
setItem(item.rows[0])
console.log(item)
})();
console.log(match)
},[match]);
console.log(product.name)
async function handleToken(token, addresses) {
const response = await axios.post(
"http://localhost:8080/checkout",
{ token, product }
);
console.log(response.status)
if (response.status === 200) {
toast("Success! Check email for details", { type: "success" });
} else {
toast("Something went wrong", { type: "error" });
}
}
return (
<div className="App">
<div className="container">
<h1 key={item.oid}></h1>
<br />
<br />
<h1 className="text-center">Stripe Checkout</h1>
<br />
<h2 className="text-center">Product Info:</h2>
<h3 className="text-center">Product Name: {item.listingTitle}</h3>
<h3 className="text-center">Product Price: {item.itemPrice}</h3>
<img className="image" src={[item.imageSelection]}width={250} height={150}></img>
<h3 className="text-center">
Product Description: {item.itemDescription}
</h3>
<br />
<div className="form-group container">
<StripeCheckout
className="center"
stripeKey=""
token={handleToken}
amount={item.itemPrice * 100}
name={item.listingTitle}
billingAddress
shippingAddress
/>
</div>
</div>
</div>
);
}
我正在尝试为将使用 stripe Checkout 的项目创建一个小型市场网站。我一直在学习教程,但它没有涵盖使用来自 API 的产品。这就是我卡住的地方。
所以首先我的 table 在包含产品的 api 中有这些字段:oid |上市标题 |项目描述 |类别选择 |图片选择 |用户邮箱 |用户电话号码
这一切都完美无缺,但有一点不同。在产品 useState 中,我试图使用数据库中的这些字段来存储名称描述和价格,然后将其发送到 stripe itsel。但是,当在 itemDescription 中发送付款时,它会在名称等方面显示相同的“未定义”。除了价格,因为我将其设置为 80 只是为了测试。
现在我的问题是如何使用产品 useState 中的信息访问 api 中的字段 我的整个代码如下:
function Item({match}) {
useEffect(() => {
fetchItem();
console.log(match)
},[]);
const [item, setItem]= useState([]);
const fetchItem= async ()=>{
const fetchItem= await fetch (`http://link //?oid=${match.params.oid}`
);
const item= await fetchItem.json();
setItem(item.rows[0])
console.log(item)
}
toast.configure()
const [product] = useState({
name: item.listingTitle,
price: "80",
description: item.itemDescription,
});
console.log(product.name)
async function handleToken(token, addresses) {
const response = await axios.post(
"http://localhost:8080/checkout",
{ token, product }
);
console.log(response.status)
if (response.status === 200) {
toast("Success! Check email for details", { type: "success" });
} else {
toast("Something went wrong", { type: "error" });
}
}
return (
<div className="App">
<div className="container">
<h1 key={item.oid}></h1>
<br />
<br />
<h1 className="text-center">Stripe Checkout</h1>
<br />
<h2 className="text-center">Product Info:</h2>
<h3 className="text-center">Product Name: {item.listingTitle}</h3>
<h3 className="text-center">Product Price: {item.itemPrice}</h3>
<img className="image" src={[item.imageSelection]}width={250} height={150}></img>
<h3 className="text-center">
Product Description: {item.itemDescription}
</h3>
<br />
<div className="form-group container">
<StripeCheckout
className="center"
stripeKey=""
token={handleToken}
amount={item.itemPrice * 100}
name={item.listingTitle}
billingAddress
shippingAddress
/>
</div>
</div>
</div>
);
}
这是每个 React 新手都面临的常见问题,这里的问题是 setState 函数不会立即更新值,而是将其提交给 React 核心系统,然后在所有代码执行后分配给该状态,所以如果您 console.log 设置后下一行的状态,您将获得旧值或未定义
这就是为什么 useEffect 钩子在这里提供帮助
要跟踪一个状态并在其他状态下使用它的值,您必须像这样使用 useEffect 挂钩,例如:useEffect(()=>{},[stateToTrack])
这里我也写了一个沙盒demo大家可以看看玩 希望这会有所帮助 demo
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [item, setItem] = useState([]);
function fetchItem() {
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((r) => r.json())
.then((r) => {
setItem(r);
});
}
const [product, setProduct] = useState({
name: "",
desc: ""
});
useEffect(fetchItem, []); // run once
useEffect(() => {
// tracking item state
setProduct({
name: item.title,
desc: item.body
});
console.log(item);
}, [item]);
return (
<>
<div style={{ fontSize: 20, fontWeight: "bold" }}>{product.name}</div>
<br />
<div>{product.desc}</div>
</>
);
}
有点Javascript的基本特征;如果您不知道它是什么,那么去学习它非常重要。本质上它在它的本地环境中“包装”了一个函数并让它 运行 somewhat-independently - 对于最简单的例子,(() => {fetchItem()})
只是 returns 一个匿名函数 运行 ; (() => {fetchItem()})();
创建它并 运行 保存它。
你还有其他问题,所以可能更接近这个(假设你只想 运行 toast.configure() 一次)
function Item({match}) {
const [item, setItem]= useState([]);
const [product, setProduct] = useState({
name: item.listingTitle,
price: "80",
description: item.itemDescription,
});
useEffect(() => {
toast.configure()
(async () => {
const fetchItem= await fetch (`http://link //?oid=${match.params.oid}`);
const item= await fetchItem.json();
setItem(item.rows[0])
console.log(item)
})();
console.log(match)
},[match]);
console.log(product.name)
async function handleToken(token, addresses) {
const response = await axios.post(
"http://localhost:8080/checkout",
{ token, product }
);
console.log(response.status)
if (response.status === 200) {
toast("Success! Check email for details", { type: "success" });
} else {
toast("Something went wrong", { type: "error" });
}
}
return (
<div className="App">
<div className="container">
<h1 key={item.oid}></h1>
<br />
<br />
<h1 className="text-center">Stripe Checkout</h1>
<br />
<h2 className="text-center">Product Info:</h2>
<h3 className="text-center">Product Name: {item.listingTitle}</h3>
<h3 className="text-center">Product Price: {item.itemPrice}</h3>
<img className="image" src={[item.imageSelection]}width={250} height={150}></img>
<h3 className="text-center">
Product Description: {item.itemDescription}
</h3>
<br />
<div className="form-group container">
<StripeCheckout
className="center"
stripeKey=""
token={handleToken}
amount={item.itemPrice * 100}
name={item.listingTitle}
billingAddress
shippingAddress
/>
</div>
</div>
</div>
);
}