📜  Unstated Next – ReactJS 的轻量级状态管理库 |部分 - 3 |购物车

📅  最后修改于: 2022-05-13 01:56:15.057000             🧑  作者: Mango

Unstated Next – ReactJS 的轻量级状态管理库 |部分 - 3 |购物车

在之前发表的文章中,我们使用 Unstated Next 实现了一个购物车。在本文中,我们将学习如何使用 Unstated Next 在React应用程序中处理多个组件的状态

先决条件:

  • 本文是上一篇的延续,请先参考。
  • 并遵循前面文章的所有先决条件。

创建简单的购物车应用程序:

第 1 步:转到您 PC 上的首选位置并打开命令提示符并键入以下命令以创建一个新的 react 应用程序。

npx create-react-app shopping-cart

第 2 步:成功创建 React 应用程序后。使用以下命令进入其目录。

cd shopping-cart

第 3 步:创建 components 文件夹以添加新组件和 store 文件夹以使用 Unstated Next 库创建全局存储。按照以下命令创建文件夹。

mkdir src/components src/store
or
mkdir src\components src\store

第 4 步:安装一个名为 Unstated Next 的软件包:

npm i unstated-next

第 5 步:要验证一切是否正常,请运行以下命令来运行您的应用程序。

npm start

项目结构:在此之后,您的文件夹结构如下所示:

第 1 步:创建多个商店

src/store文件夹中为购物车、用户和商品再创建 3 个商店。前面文章中给出的创建商店的详细说明参考了那个。

cart.js
import { useState } from "react";
import { createContainer } from "unstated-next";
  
function useCart(initialState = []) {
    let [items, setItems] = useState(initialState);
    let addItem = (_item) => {
        setItems([...items, _item]);
    };
    let deleteItem = (_item) => {
        let newItem = items.filter((item) => item !== _item);
        setItems(newItem);
    };
    return { items, addItem, deleteItem };
}
  
export default createContainer(useCart);


src/store/user.js
import { useState } from "react";
import { createContainer } from "unstated-next";
  
function useUser(initialState = []) {
    // Storing users using array 
    let [users, setUser] = useState(initialState); 
    let addUser = (_user) => {
        // Setting users list containing new user 
        setUser([...users, _user]); 
    };
    let deleteUser = (_user) => {
        // Filtering & deleting requested user 
        let newUser = users.filter((user) => user !== _user); 
        setUser(newUser);
    };
    return { users, addUser, deleteUser };
}
  
export default createContainer(useUser); 
// returns {Procider , useContainer}


src/store/item.js
import { useState } from "react";
import { createContainer } from "unstated-next";
  
function useItem(initialState = []) {
  
    // Storing items using array
    let [items, setItem] = useState(initialState);
    let addItem = (_item) => {
        // Setting items list containing new item
        setItem([...items, _item]); 
    };
    let deleteItem = (_item) => {
        // Filtering & deleting requested item
        let newItem = items.filter((item) => item !== _item); 
        setItem(newItem);
    };
    return { items, addItem, deleteItem };
}
  
// Returns {Procider , useContainer}
export default createContainer(useItem);


Cart.jsx
import React, { useState } from "react";
import "./cart.css";
import useCart from "../store/cart";
  
function Cart() {
    let { items, addItem, deleteItem } = useCart.useContainer();
    const [localItem, setLocalItem] = useState("");
    console.log(localItem, items);
    return (
        
            

Cart Items

            
                    {items.length > 0 ? (                     items.map((item) => (                         
                                
  1.                                 {item}{" "}                             
  2.                                                      
                        ))                 ) : (                     

    Cart is Empty

                    )}             
             setLocalItem(e.target.value)}             />              {                     addItem(localItem);                     setLocalItem("");                 }}             />         
    ); }    export default Cart;


src/components/User.jsx
import React from "react";
  
function User() {
    return (
        
            
                User             
                                  
    ); }    export default User;


src/components/Item.jsx
import React from "react";
  
function Item() {
    return (
        
            
                Item             
                                  
    ); }    export default Item;


cart.css
.title {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: 3rem;
    background-color: rgb(172, 172, 172);
    margin: 10vh 30vw;
    padding: 10px 22px;
    width: 40vw;
    border-radius: 5px;
}
.items {
    padding: 22px;
    width: 40vw;
    border-radius: 5px;
    margin: 10vh 30vw;
    margin-top: -9vh;
    background-color: rgb(221, 221, 171);
    font-size: 1.5rem;
    list-style-type: none;
}
.item-set {
    display: flex;
    justify-content: center;
    align-items: center;
}
.item {
    width: 10vw;
    padding: 1vw;
}
.deleteButton {
    width: 10vw;
    height: 8vh;
    font-size: 1.2rem;
    border-radius: 5px;
    border: none;
    background-color: rgb(226, 148, 148);
}
.deleteButton:hover {
    background-color: rgb(211, 101, 101);
    color: rgb(255, 253, 253);
}
#newItem {
    padding: 2vh 8vw;
    outline: none;
    border: none;
    border-bottom: 2px solid rgb(172, 170, 170);
}
#submitButton {
    padding: 10px 40px;
    font-size: 1.2rem;
    border-radius: 5px;
    border: none;
    background-color: rgb(100, 214, 167);
    margin-left: 1vw;
}
#submitButton:active {
    background-color: rgb(43, 129, 93);
    color: wheat;
}


src/store/provider.js
import React from "react";
  
import useUser from "./user";
import useCart from "./cart";
import useItem from "./item";
  
// "props" will contain Child components
// it named as "childern"
const Provider = (props) => { 
    return (
         // for cart
             // for Item
                // for user
                {props.children} 
            
        
    );
};
  
export default Provider;


App.js
import "./App.css";
import Cart from "./components/Cart";
import Item from "./components/Item";
import User from "./components/User";
import Provider from "./store/provider";
  
function App() {
    return (
        
            // it contains all 3 store providers                                                                                        
    ); }    export default App;


src/components/User.jsx
import React, { useState } from "react";
import useUser from "../store/user";
  
function User() {
    // Extracting field and methods
    const { users, addUser } = useUser.useContainer();
    // To capture user input
    const [localUser, setLocalUser] = useState(""); 
  
    return (
        
            
                {users.length > 0 &&                     // Mapping through users array                     users.map((user) => (                           

                            {user}                         

                       ))}             
             setLocalUser(e.target.value)}                  placeholder="user name"             >             // Adding new users                       
    ); }    export default User;


src/components/Item.jsx
import React, { useState } from "react";
import useItem from "../store/item";
  
function Item() {
    const { items, addItem } = useItem.useContainer();
    const [localItem, setLocalItem] = useState("");
    return (
        
            
                {items.length > 0 &&                     items.map((item) => (                         

                            {item}                         

                       ))}             
             setLocalItem(e.target.value)}                 placeholder="item name"             >                      
    ); }    export default Item;


src/store/user.js

import { useState } from "react";
import { createContainer } from "unstated-next";
  
function useUser(initialState = []) {
    // Storing users using array 
    let [users, setUser] = useState(initialState); 
    let addUser = (_user) => {
        // Setting users list containing new user 
        setUser([...users, _user]); 
    };
    let deleteUser = (_user) => {
        // Filtering & deleting requested user 
        let newUser = users.filter((user) => user !== _user); 
        setUser(newUser);
    };
    return { users, addUser, deleteUser };
}
  
export default createContainer(useUser); 
// returns {Procider , useContainer}

src/store/item.js

import { useState } from "react";
import { createContainer } from "unstated-next";
  
function useItem(initialState = []) {
  
    // Storing items using array
    let [items, setItem] = useState(initialState);
    let addItem = (_item) => {
        // Setting items list containing new item
        setItem([...items, _item]); 
    };
    let deleteItem = (_item) => {
        // Filtering & deleting requested item
        let newItem = items.filter((item) => item !== _item); 
        setItem(newItem);
    };
    return { items, addItem, deleteItem };
}
  
// Returns {Procider , useContainer}
export default createContainer(useItem); 

第 2 步:创建多个组件

接下来,我们需要在src/components文件夹中为cartusersitems创建 3 个简单组件,并将其连接到App.js文件。

购物车.jsx

import React, { useState } from "react";
import "./cart.css";
import useCart from "../store/cart";
  
function Cart() {
    let { items, addItem, deleteItem } = useCart.useContainer();
    const [localItem, setLocalItem] = useState("");
    console.log(localItem, items);
    return (
        
            

Cart Items

            
                    {items.length > 0 ? (                     items.map((item) => (                         
                                
  1.                                 {item}{" "}                             
  2.                                                      
                        ))                 ) : (                     

    Cart is Empty

                    )}             
             setLocalItem(e.target.value)}             />              {                     addItem(localItem);                     setLocalItem("");                 }}             />         
    ); }    export default Cart;

src/components/User.jsx

import React from "react";
  
function User() {
    return (
        
            
                User             
                                  
    ); }    export default User;

src/components/Item.jsx

import React from "react";
  
function Item() {
    return (
        
            
                Item             
                                  
    ); }    export default Item;

购物车.css

.title {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: 3rem;
    background-color: rgb(172, 172, 172);
    margin: 10vh 30vw;
    padding: 10px 22px;
    width: 40vw;
    border-radius: 5px;
}
.items {
    padding: 22px;
    width: 40vw;
    border-radius: 5px;
    margin: 10vh 30vw;
    margin-top: -9vh;
    background-color: rgb(221, 221, 171);
    font-size: 1.5rem;
    list-style-type: none;
}
.item-set {
    display: flex;
    justify-content: center;
    align-items: center;
}
.item {
    width: 10vw;
    padding: 1vw;
}
.deleteButton {
    width: 10vw;
    height: 8vh;
    font-size: 1.2rem;
    border-radius: 5px;
    border: none;
    background-color: rgb(226, 148, 148);
}
.deleteButton:hover {
    background-color: rgb(211, 101, 101);
    color: rgb(255, 253, 253);
}
#newItem {
    padding: 2vh 8vw;
    outline: none;
    border: none;
    border-bottom: 2px solid rgb(172, 170, 170);
}
#submitButton {
    padding: 10px 40px;
    font-size: 1.2rem;
    border-radius: 5px;
    border: none;
    background-color: rgb(100, 214, 167);
    margin-left: 1vw;
}
#submitButton:active {
    background-color: rgb(43, 129, 93);
    color: wheat;
}

第 3 步:将 Providers 移动到 provider.js 文件:这一步非常重要,因为在之前的教程中,我们将 Provider 直接添加到了App.js文件中。因此,每次我们创建新商店时,我们都需要这样做。这使得App.js文件非常复杂,为避免这种情况,我们将所有提供程序添加到一个文件中,然后将其导入到App.js文件中。

为此,我们需要在src/store中创建一个provider.js文件,然后添加以下代码。

src/store/provider.js

import React from "react";
  
import useUser from "./user";
import useCart from "./cart";
import useItem from "./item";
  
// "props" will contain Child components
// it named as "childern"
const Provider = (props) => { 
    return (
         // for cart
             // for Item
                // for user
                {props.children} 
            
        
    );
};
  
export default Provider;

因此,每当您创建新商店时,您只需在此处添加即可。

现在我们需要将 Provider 导入App.js

应用程序.js

import "./App.css";
import Cart from "./components/Cart";
import Item from "./components/Item";
import User from "./components/User";
import Provider from "./store/provider";
  
function App() {
    return (
        
            // it contains all 3 store providers                                                                                        
    ); }    export default App;

第 4 步:在组件中使用 Store

我们需要将useContainer导入到各个组件中以使用商店数据。按照以下代码导入消费商店数据和方法。

  • src/components/User.jsx:用这个替换之前的代码

src/components/User.jsx

import React, { useState } from "react";
import useUser from "../store/user";
  
function User() {
    // Extracting field and methods
    const { users, addUser } = useUser.useContainer();
    // To capture user input
    const [localUser, setLocalUser] = useState(""); 
  
    return (
        
            
                {users.length > 0 &&                     // Mapping through users array                     users.map((user) => (                           

                            {user}                         

                       ))}             
             setLocalUser(e.target.value)}                  placeholder="user name"             >             // Adding new users                       
    ); }    export default User;

src/components/Item.jsx:用这个替换之前的代码

src/components/Item.jsx

import React, { useState } from "react";
import useItem from "../store/item";
  
function Item() {
    const { items, addItem } = useItem.useContainer();
    const [localItem, setLocalItem] = useState("");
    return (
        
            
                {items.length > 0 &&                     items.map((item) => (                         

                            {item}                         

                       ))}             
             setLocalItem(e.target.value)}                 placeholder="item name"             >                      
    ); }    export default Item;

输出:

结论:我们通过创建一个单独的Provider.js文件成功地处理了多个商店。我希望您理解所有概念,以防您需要任何澄清,请随时在下面发表评论。