使用 useState 和 useEffect 构建 React Hooks 购物车
视频演示
Hooks 文章解释
视频演示
在 YouTube 上订阅以获取更多内容。
Hooks 文章解释
在本文中,我们将使用钩子来创建视频游戏商店和购物车。
首先,我将展示一个如何使用 useState 钩子的示例。
import React, { useState } from "react";
const Shop = () => {
const [open, setOpen] = useState(true);
console.log(open)
const closeStore = () => {
setOpen(false)
}
return(
<div>
<input type="submit" value="close" onClick={() => closeStore()} />
</div>
)
}
export default Shop;
在这个例子中,open是一个键,它将useState参数作为其值。useState( true ), open = true。
setOpen是一个以值作为参数的函数。
setOpen将把open设置为传递给setOpen 的新值。
setOpen(false),设置open = false
这显示了一个按钮,单击该按钮可以将open的值从 true 更改为 false。
让我们尝试一个更复杂的用例。
在 App.js 中,我们将返回一个包含即将创建的 Shop 组件的 div:
import React from "react";
import Shop from "./shop/Shop";
function App() {
return (
<div>
<Shop />
</div>
);
}
export default App;
接下来我们将创建 shop 组件。在 src 中创建一个名为 shop 的文件夹。然后在该文件夹中创建一个名为 Shop.js 的文件。
完成的Shop.js代码在文章底部。
我们将返回一个空的功能组件来帮助我们开始:
import React, { useState, useEffect } from "react";
const Shop = () => {
return <div />
}
export default Shop;
让我们将库存添加为标记为 items 的数组:
const Shop = () => {
const items = [
{
id: 1,
name: "overwatch",
price: 20,
},
{
id: 2,
name: "minecraft",
price: 32,
},
{
id: 3,
name: "fortnite",
price: 51,
},
];
return <div />
}
我们只销售这三款电子游戏。我们需要展示它们。因此,我们将使用 .map() 创建一个名为 listItems 的新格式化数组。现在,我们应该返回 listItems:
const listItems = items.map((el) => (
<div key={el.id}>
{`${el.name}: $${el.price}`}
<input type="submit" value="add" onClick={() => addToCart(el)} />
</div>
));
return(<div>{listItems}</div>)
在以上各项中,我们将创建第一个 useState 钩子:
const [cart, setCart] = useState([]);
const cart用来保存购物车的状态。我们可以调用setCart()并传入想要对cart进行的状态更改。让我们使用 setCart 创建 addToCart 函数:
const addToCart = (el) => {
setCart([...cart, el]);
};
addToCart 获取选定的元素并将其添加到购物车数组。
我们将在应用中的商店下显示购物车。首先,根据购物车数组创建一个新的格式化数组:
const cartItems = cart.map((el) => (
<div key={el.id}>
{`${el.name}: $${el.price}`}
<input type="submit" value="remove" onClick={() => removeFromCart(el)} />
</div>
));
我们可以使用过滤方法创建 removeFromCart 函数。注意*我们将在过滤之前复制购物车状态:
const removeFromCart = (el) => {
let hardCopy = [...cart];
hardCopy = hardCopy.filter((cartItem) => cartItem.id !== el.id);
setCart(hardCopy);
};
更改返回语句以包含 cartItems:
return (
<div>
STORE
<div>{listItems}</div>
<div>CART</div>
<div>{cartItems}</div>
</div>
);
最后,我们将跟踪 useState 和 useEffect 的总体使用情况:
const [cartTotal, setCartTotal] = useState(0);
useEffect(() => {
total();
}, [cart]);
const total = () => {
let totalVal = 0;
for (let i = 0; i < cart.length; i++) {
totalVal += cart[i].price;
}
setCartTotal(totalVal);
};
useEffect hooks 包含一个箭头函数。在箭头函数内部,我们调用了我们的 total 函数。
useEffect 中的第二个参数是包含 [ cart ]的依赖数组。
useEffect 会检测其依赖项数组中命名的变量的变化。当它检测到变化时,就会再次运行。
每次从购物车中添加或删除商品时,useEffect 都会检测购物车的变化并运行总计函数。
最后,将总计放入您的回报中:
import React, { useState, useEffect } from "react";
const Shop = () => {
const [cart, setCart] = useState([]);
const [cartTotal, setCartTotal] = useState(0);
const items = [
{
id: 1,
name: "overwatch",
price: 20,
},
{
id: 2,
name: "minecraft",
price: 32,
},
{
id: 3,
name: "fortnite",
price: 51,
},
];
useEffect(() => {
total();
}, [cart]);
const total = () => {
let totalVal = 0;
for (let i = 0; i < cart.length; i++) {
totalVal += cart[i].price;
}
setCartTotal(totalVal);
};
const addToCart = (el) => {
setCart([...cart, el]);
};
const removeFromCart = (el) => {
let hardCopy = [...cart];
hardCopy = hardCopy.filter((cartItem) => cartItem.id !== el.id);
setCart(hardCopy);
};
const listItems = items.map((el) => (
<div key={el.id}>
{`${el.name}: $${el.price}`}
<input type="submit" value="add" onClick={() => addToCart(el)} />
</div>
));
const cartItems = cart.map((el) => (
<div key={el.id}>
{`${el.name}: $${el.price}`}
<input type="submit" value="remove" onClick={() => removeFromCart(el)} />
</div>
));
return (
<div>
STORE
<div>{listItems}</div>
<div>CART</div>
<div>{cartItems}</div>
<div>Total: ${cartTotal}</div>
</div>
);
};
export default Shop;
观看视频了解更多!接下来,我们将重构此代码以使用 Redux。之后,我们将开始使用 fetch api 和 redux-thunk 发出 http 请求。最后,我们将项目转换为 redux-saga。视频已上传至 YouTube频道链接,文章也即将发布!
文章来源:https://dev.to/papasanto/build-a-react-hooks-shopping-cart-with-usestate-and-useeffect-39hk