首页 > 解决方案 > React中如何初始化组件数组中每个item组件的状态?

问题描述

const products = [
    {
      id: 1,
      ...
    },
    {
      id: 2,
      ...
    },
    {
      id: 3,
      ...
    },
];

我创建了 ProductList 组件,其中包含 3 个 Product 组件:

    class ProductList extends Component {

      constructor(props) {
       super(props)
      }

      render() {
        const productComponents = products.map((product) => (
           <Product 
                key = {'product-' + product.id}
                id = {product.id}
                ...
            />
        ));
        return ( 
              <ul className="holder-list row">
                {productComponents}
              </ul> 
        );
       }
     }

     class Product extends Component {
       constructor(props) {
       super(props)
      }
       render() {
         return(..)
       }
     }

如何以及在构造函数中的哪个组件中为所有三个产品设置不同的初始状态?

我想为每个产品设置不同的 this.state 的初始值。

例子:

对于 id:1 的产品 - this.state={color: blue},

对于 id:2 的产品 - this.state={color: yellow},

对于 id:3 的产品 - this.state={color: red}

我怎么能做这样的事情?

标签: reactjs

解决方案


这就是您可以设置状态color的方法Product。这些都来自一篇很棒的文章你可能不需要派生状态,它提供了一些关于如何处理“派生状态”的很好的例子。

ProductList - 创建一个方法,根据您的 id 到颜色要求返回字符串颜色值。这可以在类定义之外,它不需要/不应该是类上的方法,ProductList因为它不需要this或类似的。添加一个额外的道具,例如defaultColor,传递给每个实例Product

const getColor = id => {
  switch (id) {
    case 1:
      return 'blue';
    case 2:
      return 'yellow';
    case 3:
      return 'red'
    default:
      return '';
  }
};

// ...

render() {
  const productComponents = products.map((product) => (
    <Product 
      key = {'product-' + product.id}
      id = {product.id}
      defaultColor={getColor(product.id)}
      ...
    />
  ));
}

Product - 使用defaultColor传入的 prop 设置初始状态。使用不同的属性将允许每个Product组件完全控制它自己的颜色状态值/使用类似的东西更改<input />,但复制初始颜色值:

class Product extends Component {
  state = { color: this.props.defaultColor };

  // ...

  render() {
    return ({/* ... */});
  }
}

这是一个StackBlitz演示实际功能。

其他选项Product. 它有条件地检查id道具是否已更改,以避免不必要地设置状态并覆盖Product本地状态值。我们正在跟踪先前的id值,以便可以在条件语句中使用它来查看是否实际发生了任何更改:

class Product extends Component {
  constructor(props) {
    super(props);

    this.state = {
      prevId: -1,
      color: ''
    };
  }

  static getDerivedStateFromProps(props, state) {
    if (props.id !== state.prevId) {
      switch (props.id) {
        case 1:
          return { color: 'blue', prevId: props.id };
        case 2:
          return { color: 'yellow', prevId: props.id };
        case 3:
          return { color: 'red', prevId: props.id };
        default:
          return null;
      }
    }

    return null
  }

  render() {
    return ({/* ... */});
  }
}

这是一个演示此功能的StackBlitz 。

很难确切地说出如何解决这个问题,因为您可能不需要在Product. 这Product可以充当一个“哑”组件,只是接收道具并将值更改为更高阶的组件,例如ProductList.

希望这会有所帮助!


推荐阅读