(Next/react) SWR 从子组件中的按钮单击刷新 - 我可以使用回调吗? (功能到功能)
(Next/react) SWR refresh from button click in child component - can I use a callback?? (function to function)
我正在使用 Next.js 制作购物车组件,更新后刷新购物车数据时遇到问题。我的购物车组件是 Next.js 文档 (https://nextjs.org/docs/basic-features/data-fetching#fetching-data-on-the-client-side) 中推荐的功能,我在其中有一个名为 products.js 的组件,其中包含我的产品列表,每个产品都有 +/- 按钮调整他们的数量(post 到数据库)。
我的数据库更新了,但我需要在购物车组件上重新获取数据客户端。我意识到我可以使用 swrs 'mutate' 重新获取 swr 调用,但是当我尝试将回调函数从我的 cart.js 传递到 products.js 时,它会显示在控制台日志中,但是没有在我的按钮点击时被调用。
我已经尝试 cartUpdate = cartUpdate.bind(this)
并且最近几天还研究了 hooks 并尝试了其他东西但可以使用一些建议。
如果 cart.js 是一个 class 组件,我会在将其传递给 product.js 之前绑定我的 cartUpdate
函数,这会起作用,但我似乎无法在功能正常时做同样的事情 vs class 功能。
我已经处理这几天了,我不确定我是否试图违反一些我不知道的规则,或者我如何才能重新获取我的数据,同时仍然保留我的数据代码分开并且有点干净。
products.js:
export default function productsection ({products, cart, cartproducts, feUpdate}){
console.log("feUpdate", feUpdate)
return (
<div>
{products.map((product, i) => (
<div className="flex-column justify-content-center mx-2">
<div className="mx-auto card w-100 p-2 my-2">
<div className="card-body ">
<h5 className="card-title text-center">{product.name}</h5>
<div className="d-flex justify-content-between">
{/* <p>Size Selected: {product.size}</p> */}
{/* <p>Total: {product.price * props.cartproducts[i].qty} USD</p> */}
<button className='btn btn-light mx-2' onClick={() => {
fetch(`/api/db/editCartProducts`,{
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({task: 'ADD', orderid: cart.orderid, productid: product.productid})
}).then(res => {console.log("adding: " + product.name + " from cart.", "id: " + product.productid); () => feUpdate(); console.log("passed update")})
}}
>
Add
</button>
<p className="px-2">Price: {product.price} USD EA</p>
<p className="px-2">{product.description}</p>
<p>Quantity: {cartproducts[i].qty}</p>
<button className='btn btn-light mx-2' onClick={() => {
fetch(`/api/db/editCartProducts`,{
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({task: 'REMOVE', orderid: cart.orderid, productid: product.productid})
}).then(res => {console.log("removing: " + product.name + " from cart.", "id: " + product.productid);() => feUpdate(); console.log("passed update")})
}}>
Remove
</button>
</div>
</div>
</div>
</div>
))}
</div>
)
}
cart.js:(要点是 cartUpdate()
和 ProductSection
,我将 cartUpdate
传递给它)
function Cart (props){
const fetcher = (...args) => fetch(args[0], {
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({[args[2]]:args[1]})
}).then(res => res.json())
let User = Cookies.get('User')
async function cartUpdate(){
console.log("mutate called");
console.log("isValidated: ", isValidating)
mutate();
console.log(cartitems);
console.log("isValidated: ", isValidating)
}
const { data: user, error} = useSWR(() => [url1, User, "User"], fetcher, {suspense: false });
console.log("User returned: ", user)
const { data: cart, error2} = useSWR(() => [url2, user.customerid, 'User'], fetcher, { suspense: false });
console.log("Cart returned: ", cart)
// const OrderId = Cookies.get('orderid')
const { data: cartitems, error3, mutate, isValidating} = useSWR(() => [url3, cart.orderid, 'orderid'], fetcher, { suspense: false });
console.log("Cart items: ", cartitems)
console.log("before productdetails call")
const { data: productdetails, error4} = useSWR(() => [url4, cartitems, 'productids'], fetcher, { suspense: false });
console.log("productdetails: ", productdetails)
let itemtotal = 0;
let costtotal = 0;
if(productdetails && cartitems){
productdetails.forEach((product, i) => {
itemtotal = itemtotal + (cartitems[i].qty);
costtotal = costtotal + (product.price * cartitems[i].qty)
})
console.log("totals: ", itemtotal, costtotal)
}
if (productdetails) {
console.log(props)
// foreach to get total price of cart and total items count.
return (
<div className="jumbotron jumbotron-fluid mt-5 d-flex flex-column justify-content-center">
<Header name={user.fname}/>
<div className={!isValidating? "card text-center" : "text-center"}>isValidating??</div>
<div className="d-flex flex-row justify-content-center">
<button onClick={() => feUpdate()}>Big Update Button</button>
<ProductSection feUpdate={cartUpdate} products={productdetails} cart={cart} cartproducts={cartitems} />
<Summery itemtotal={itemtotal} costtotal={costtotal}/>
</div>
</div>
)
}
您是否在使用全局 mutate
(是的,其中有 2 个)?然后你需要给它传递一个SWR密钥。
全球mutate
:
import useSWR, { mutate } from 'swr'
...
const { data } = useSWR(key, fetcher)
mutate(key) // this will trigger a refetch
或者使用绑定mutate
,你不需要传递key
:
import useSWR from 'swr'
...
const { data, mutate } = useSWR(key, fetcher)
mutate() // this will trigger a refetch
所以为了结束这个,我在处理了项目的其他领域之后又回到了它,并意识到它就像使用普通函数调用而不是箭头函数一样简单,例如.then(res => {feUpdate()})
不知道我是如何忽略这一点的,也不知道之前的测试是怎么回事,但它现在可以正常工作了。我想休息一下,然后带着新鲜的眼睛回来就可以了。
我正在使用 Next.js 制作购物车组件,更新后刷新购物车数据时遇到问题。我的购物车组件是 Next.js 文档 (https://nextjs.org/docs/basic-features/data-fetching#fetching-data-on-the-client-side) 中推荐的功能,我在其中有一个名为 products.js 的组件,其中包含我的产品列表,每个产品都有 +/- 按钮调整他们的数量(post 到数据库)。
我的数据库更新了,但我需要在购物车组件上重新获取数据客户端。我意识到我可以使用 swrs 'mutate' 重新获取 swr 调用,但是当我尝试将回调函数从我的 cart.js 传递到 products.js 时,它会显示在控制台日志中,但是没有在我的按钮点击时被调用。
我已经尝试 cartUpdate = cartUpdate.bind(this)
并且最近几天还研究了 hooks 并尝试了其他东西但可以使用一些建议。
如果 cart.js 是一个 class 组件,我会在将其传递给 product.js 之前绑定我的 cartUpdate
函数,这会起作用,但我似乎无法在功能正常时做同样的事情 vs class 功能。
我已经处理这几天了,我不确定我是否试图违反一些我不知道的规则,或者我如何才能重新获取我的数据,同时仍然保留我的数据代码分开并且有点干净。
products.js:
export default function productsection ({products, cart, cartproducts, feUpdate}){
console.log("feUpdate", feUpdate)
return (
<div>
{products.map((product, i) => (
<div className="flex-column justify-content-center mx-2">
<div className="mx-auto card w-100 p-2 my-2">
<div className="card-body ">
<h5 className="card-title text-center">{product.name}</h5>
<div className="d-flex justify-content-between">
{/* <p>Size Selected: {product.size}</p> */}
{/* <p>Total: {product.price * props.cartproducts[i].qty} USD</p> */}
<button className='btn btn-light mx-2' onClick={() => {
fetch(`/api/db/editCartProducts`,{
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({task: 'ADD', orderid: cart.orderid, productid: product.productid})
}).then(res => {console.log("adding: " + product.name + " from cart.", "id: " + product.productid); () => feUpdate(); console.log("passed update")})
}}
>
Add
</button>
<p className="px-2">Price: {product.price} USD EA</p>
<p className="px-2">{product.description}</p>
<p>Quantity: {cartproducts[i].qty}</p>
<button className='btn btn-light mx-2' onClick={() => {
fetch(`/api/db/editCartProducts`,{
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({task: 'REMOVE', orderid: cart.orderid, productid: product.productid})
}).then(res => {console.log("removing: " + product.name + " from cart.", "id: " + product.productid);() => feUpdate(); console.log("passed update")})
}}>
Remove
</button>
</div>
</div>
</div>
</div>
))}
</div>
)
}
cart.js:(要点是 cartUpdate()
和 ProductSection
,我将 cartUpdate
传递给它)
function Cart (props){
const fetcher = (...args) => fetch(args[0], {
method: 'post',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({[args[2]]:args[1]})
}).then(res => res.json())
let User = Cookies.get('User')
async function cartUpdate(){
console.log("mutate called");
console.log("isValidated: ", isValidating)
mutate();
console.log(cartitems);
console.log("isValidated: ", isValidating)
}
const { data: user, error} = useSWR(() => [url1, User, "User"], fetcher, {suspense: false });
console.log("User returned: ", user)
const { data: cart, error2} = useSWR(() => [url2, user.customerid, 'User'], fetcher, { suspense: false });
console.log("Cart returned: ", cart)
// const OrderId = Cookies.get('orderid')
const { data: cartitems, error3, mutate, isValidating} = useSWR(() => [url3, cart.orderid, 'orderid'], fetcher, { suspense: false });
console.log("Cart items: ", cartitems)
console.log("before productdetails call")
const { data: productdetails, error4} = useSWR(() => [url4, cartitems, 'productids'], fetcher, { suspense: false });
console.log("productdetails: ", productdetails)
let itemtotal = 0;
let costtotal = 0;
if(productdetails && cartitems){
productdetails.forEach((product, i) => {
itemtotal = itemtotal + (cartitems[i].qty);
costtotal = costtotal + (product.price * cartitems[i].qty)
})
console.log("totals: ", itemtotal, costtotal)
}
if (productdetails) {
console.log(props)
// foreach to get total price of cart and total items count.
return (
<div className="jumbotron jumbotron-fluid mt-5 d-flex flex-column justify-content-center">
<Header name={user.fname}/>
<div className={!isValidating? "card text-center" : "text-center"}>isValidating??</div>
<div className="d-flex flex-row justify-content-center">
<button onClick={() => feUpdate()}>Big Update Button</button>
<ProductSection feUpdate={cartUpdate} products={productdetails} cart={cart} cartproducts={cartitems} />
<Summery itemtotal={itemtotal} costtotal={costtotal}/>
</div>
</div>
)
}
您是否在使用全局 mutate
(是的,其中有 2 个)?然后你需要给它传递一个SWR密钥。
全球mutate
:
import useSWR, { mutate } from 'swr'
...
const { data } = useSWR(key, fetcher)
mutate(key) // this will trigger a refetch
或者使用绑定mutate
,你不需要传递key
:
import useSWR from 'swr'
...
const { data, mutate } = useSWR(key, fetcher)
mutate() // this will trigger a refetch
所以为了结束这个,我在处理了项目的其他领域之后又回到了它,并意识到它就像使用普通函数调用而不是箭头函数一样简单,例如.then(res => {feUpdate()})
不知道我是如何忽略这一点的,也不知道之前的测试是怎么回事,但它现在可以正常工作了。我想休息一下,然后带着新鲜的眼睛回来就可以了。