简体   繁体   English

连接不同组件的状态

[英]Connecting states with different components

I have app with three different components.我的应用程序包含三个不同的组件。 In ProductList component (comp.) I have a list of available products which are in shop.在 ProductList 组件 (comp.) 中,我有一个商店中可用产品的列表。 After I click on element from this list it should appears in ShoppingList comp.在我单击此列表中的元素后,它应该出现在 ShoppingList comp 中。 and it works after I applied states and transfer it in App comp.它在我应用状态并将其传输到 App comp 后起作用。 Then it is possible to remove from Shopping list after click on element and it works thanks to useEffect but user of app should be able to add new product whenever something had been deleted.然后可以在单击元素后从购物列表中删除,这要归功于 useEffect 但应用程序的用户应该能够在删除某些内容时添加新产品。

In my code when user add some products, next delete one or two and after that user want add somethind new application render from the beginning all array.在我的代码中,当用户添加一些产品时,接下来删除一两个,然后用户想要添加一些新的应用程序从头开始呈现所有数组。 Example of shopping list: appears: milk, bread, juice -> (user deleted juice) -> appears: milk, bread -> (user add butter) -> appears: milk, bread, juice, butter (should appear: milk, bread, butter).购物清单示例:出现:牛奶、面包、果汁->(用户删除果汁)->出现:牛奶、面包->(用户添加黄油)->出现:牛奶、面包、果汁、黄油(应该出现:牛奶、牛油面包)。

In my code I have connected array which was filtered by deleted elements and send it to my ProductList to modify productsToBuy by using props.sendRemovedProductsToParent(productList).在我的代码中,我连接了按删除元素过滤的数组,并将其发送到我的 ProductList 以使用 props.sendRemovedProductsToParent(productList) 修改 productsToBuy。 I thought if I delete elements from array at the beginning I should "repair" this array which I use call in useState.我想如果我一开始就从数组中删除元素,我应该“修复”这个我在 useState 中调用的数组。 But it doesnt works.但它不起作用。

Maybe I should unmount Shopping list after delete items and load again or I have to send "remove" function to ShoppingList component?也许我应该在删除项目后卸载购物清单并再次加载,或者我必须将“删除” function 发送到 ShoppingList 组件?

I have use function component and class component to practice.我已经使用 function 组件和 class 组件进行练习。

App应用程序

 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>
  );
}

ShopingList购物清单

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>
  );
}

ProductList产品列表

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>
    );
  }
}

If you want to use some states in different components, you have to use a state management like React context or redux or others.如果你想在不同的组件中使用一些状态,你必须使用 state 管理,如 React context 或 redux 或其他。

If your states are not too big and the logic is not complex you can implement it with react context.如果你的状态不是太大并且逻辑不复杂你可以用反应上下文来实现它。

it's a simple example for that.这是一个简单的例子。 you can edit it and use in your app.您可以对其进行编辑并在您的应用中使用。

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 };

and in the index you can wrap the app with context provider:在索引中,您可以使用上下文提供程序包装应用程序:

 <ProductProvider>
      <App />
 </ProductProvider>

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

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