繁体   English   中英

连接不同组件的状态

[英]Connecting states with different components

我的应用程序包含三个不同的组件。 在 ProductList 组件 (comp.) 中,我有一个商店中可用产品的列表。 在我单击此列表中的元素后,它应该出现在 ShoppingList comp 中。 它在我应用状态并将其传输到 App comp 后起作用。 然后可以在单击元素后从购物列表中删除,这要归功于 useEffect 但应用程序的用户应该能够在删除某些内容时添加新产品。

在我的代码中,当用户添加一些产品时,接下来删除一两个,然后用户想要添加一些新的应用程序从头开始呈现所有数组。 购物清单示例:出现:牛奶、面包、果汁->(用户删除果汁)->出现:牛奶、面包->(用户添加黄油)->出现:牛奶、面包、果汁、黄油(应该出现:牛奶、牛油面包)。

在我的代码中,我连接了按删除元素过滤的数组,并将其发送到我的 ProductList 以使用 props.sendRemovedProductsToParent(productList) 修改 productsToBuy。 我想如果我一开始就从数组中删除元素,我应该“修复”这个我在 useState 中调用的数组。 但它不起作用。

也许我应该在删除项目后卸载购物清单并再次加载,或者我必须将“删除” function 发送到 ShoppingList 组件?

我已经使用 function 组件和 class 组件进行练习。

应用程序

 function App() {
  const [resultToDisplay, setResultToDisplay] = useState(``);
  const [resultRemoved, setResultRemoved] = useState(``);

  return (
    <div className={styles.appWrapper}>
      <AddProducts />
      <ProductsFilters />
      <div className={styles.columnsWrapper}>
        <ProductsList
          productsToDisplay={produkty}
          sendAddedProductsToParent={setResultToDisplay}
          resultRemoved={resultRemoved}
        />
        <ShopingList
          resultToDisplay={resultToDisplay}
          sendRemovedProductsToParent={setResultRemoved}
        />
      </div>
    </div>
  );
}

购物清单

function ShopingList(props) {
  const [productList, setProductList] = useState(props.resultToDisplay);

  useEffect(() => {
    setProductList(props.resultToDisplay);
  }, [props.resultToDisplay]);

  function removeClick(e, index) {
    e.preventDefault();
    // console.log(index);
    // console.log(productList);
    setProductList(productList.filter((currProduct, i) => i !== index));
    props.sendRemovedProductsToParent(productList);
  }

  return (
    <div className={commonColumnsStyles.App}>
      <header className={commonColumnsStyles.AppHeader}>
        <p>Shoping List</p>
        <ul>
          {productList.length
            ? productList.map((currProduct, index) => (
                <li onContextMenu={(e) => removeClick(e, index)} key={index}>
                  {currProduct.nazwa}
                </li>
              ))
            : null}
        </ul>
      </header>
    </div>
  );
}

产品列表

class ProductsList extends React.Component {
  constructor(props) {
    super(props);
    this.state = { productsToBuy: this.props.resultRemoved };

    this.addProduct = this.addProduct.bind(this);
  }

  addProduct(index) {
    console.log(this.props.resultRemoved);
    const toBuy = Array.from(this.state.productsToBuy);
    toBuy.push(this.props.productsToDisplay[index]);
    this.setState({
      productsToBuy: toBuy,
    });
    this.props.sendAddedProductsToParent(toBuy);
    // console.log(toBuy);
  }

  render() {
    return (
      <div className={commonColumnsStyles.App}>
        <header className={commonColumnsStyles.AppHeader}>
          <p>Products list</p>
          <ul>
            {this.props.productsToDisplay.map((currProduct, index) => (
              <li key={index} onClick={() => this.addProduct(index)}>
                {currProduct.nazwa}
              </li>
            ))}
          </ul>
        </header>
      </div>
    );
  }
}

如果你想在不同的组件中使用一些状态,你必须使用 state 管理,如 React context 或 redux 或其他。

如果你的状态不是太大并且逻辑不复杂你可以用反应上下文来实现它。

这是一个简单的例子。 您可以对其进行编辑并在您的应用中使用。

import React, { createContext, useState } from 'react';

const ProductContext = createContext();

function ProductProvider({ children }) {
  const [products, setProducts] = useState([]);

  function addProduct(product) {
    setProducts([...products, product]);
  }

  function deleteProduct(productId) {
    setProducts(products.filter(product => product.id !== productId));
  }

  return (
    <ProductContext.Provider value={{ products, addProduct, deleteProduct }}>
      {children}
    </ProductContext.Provider>
  );
}

export { ProductContext, ProductProvider };

在索引中,您可以使用上下文提供程序包装应用程序:

 <ProductProvider>
      <App />
 </ProductProvider>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM