使用来自智能合约的项目更新 React JS 中的状态数组

Update state array in React JS with item from Smart Contract

我在 React 中有一个状态数组,我正在尝试从智能合约中添加项目

状态数组初始化为

const [产品, setProducts] = useState([]);

  1. 和下面的 2. 不起作用,但是 3. 当数组设置在循环外时确实起作用

我在 1. 和 2 中做错了什么?

——————————————————————

  1. 没用
  for (var i = 1; i <= productCount; i++) {
        const product = await marketplace.methods.products(i).call()
        setProducts({
          products: [...this.state.products, product]
        })
      }

——————————————————————

  1. 没用
  for (var i = 1; i <= productCount; i++) {
        const product = await marketplace.methods.products(i).call()
         setProducts(prevState => ({
            products: [...prevState.products, product]
         }))
      }

——————————————————————

  1. 工作
  let productArray =[]
  for (var i = 1; i <= productCount; i++) {
        const product = await marketplace.methods.products(i).call()
        productArray.push[product]
      }
  setProduct(productArray)

——————————————————————

您使用的是功能组件,而不是 class 组件,因此您不应该使用 thisthis.state - 这就是 (1) 不起作用的原因.

(2) 不起作用,因为您的初始产品是 普通数组 - 它不是具有 products 属性 的对象:

const [products, setProducts] = useState([]);

所以

     setProducts(prevState => ({
        products: [...prevState.products, product]
     }))

没有意义 - prevState 是一个数组,而不是具有 products 属性.

的对象

稍微调整一下,(2) 就可以工作了:

     setProducts(prevState => ([...prevState, product]));

也几乎可以肯定不需要使用 .call,您可以使用 Promise.all 来加快这个过程,而不是等待每个函数单独完成:

Promise.all(
  Array.from(
    { length: productCount },
    (_, i) => marketplace.methods.products(i + 1)()
  )
)
  .then((newProducts) => {
    setProducts([...products, ...newProducts]);
  })
  // .catch(handleErrors);

如果您的代码允许您一次发出所有请求,那是我更喜欢的版本。

1 和 2 违反了 React 中 hooks 的基本规则之一。

Only Call Hooks at the Top Level。即你应该避免在循环、嵌套函数或条件中调用钩子。

同样如前所述,考虑到您使用的是 React 钩子这一事实,没有理由在第一种方法中使用 this

docs 上阅读有关 Hooks 规则的更多信息。