渲染在有条件的 for 循环中做出react

IT技术 javascript reactjs
2021-05-06 02:37:33

我在网页中有一个静态信息。

class MyStaticWebPage extends React.Component {
  render() {
    return (
      <TopContainer>
        <IconListContainer>
          <LeftButton
            Icon={MyIcon1}
            color="#ffffff"
            text="text1"
          />
          <CenterButton
            Icon={MyIcon2}
            color="#eeeeee"
            text="text2"
          />
          <RightButton
            Icon={MyIcon3}
            color="#dddddd"
            text="text3"
          />
        </IconListContainer>
        <IconListContainer>
          <LeftButton
            Icon={MyIcon4}
            color="#cccccc"
            text="text4"
          />
        </IconListContainer>
      </TopContainer>
    );
  }
}

这个页面静态显示在一个行列表中,每行最多三个图标,现在我想动态地打开它们,假设我将图标props存储在一个props数组中。

[
  {
    icon: 'MyIcon1',
    color: '#ffffff',
    text: 'text1'
  },
  {
    icon: 'MyIcon2',
    color: '#eeeeee',
    text: 'text2'
  },
  {
    icon: 'MyIcon3',
    color: '#dddddd',
    text: 'text3'
  },
  {
    icon: 'MyIcon4',
    color: '#cccccc',
    text: 'text4'
  }
]

最后使用这个 props 数组使页面自动呈现。

class MyStaticWebPage extends React.Component {
  render() {
    var rows = []
    for (var i = 0; i <= parseInt(iconNum / 3); i++) {
      // row level for loop
      // rows.push(row)
      for (var j = iconNum; j % 3 !== 0; j--) {
        // icon level for loop
        // rows.push(icon)
      }
    }
    return (
      <TopContainer>
        {rows}
      </TopContainer>
    );
  }
}

如何通过真实的react代码来解决这个问题?

4个回答

鉴于您有一个平面数组,但想要以三行呈现它,您应该做的第一件事就是将数组分块。Lodash 有一个方法,或者你可以对你的数组做一个足够简单的减少。

const chunkedArray = icons.reduce((reduction, icon, index) => {
  index % 3 ? reduction[reduction.length - 1].push(icon) : reduction.push([icon])
  return reduction
}, [])

现在您的数据具有正确的形状,我们可以轻松地将其映射到输出 jsx。

class IconListWrapper extends React.Component {
  render() {
    const { subList } = this.props
    const buttonTypes = ['LeftButton', 'CenterButton', 'RightButton']
    const Element = buttonTypes[index]
    return (
      <IconListContainer>
        {subList.map((icon, index) => <Element
            Icon={MyIcon1}
            color="#ffffff"
            text="text1"
          />)}
      </IconListContainer>
    );
  }
}

class MyStaticWebPage extends React.Component {
  render() {
    return (
      <TopContainer>
        {chunkedArray.map((subList) => <IconListWrapper subList={subList} />)}
      </TopContainer>
    );
  }
}

我想你问如何确保你组的图标到使用三组LeftButtonCenterButtonRightButton

我假设你从这样的事情开始:

var icons = [
  {
    icon: 'MyIcon1',
    color: '#ffffff',
    text: 'text1'
  },
  {
    icon: 'MyIcon2',
    color: '#eeeeee',
    text: 'text2'
  },
  {
    icon: 'MyIcon3',
    color: '#dddddd',
    text: 'text3'
  },
  {
    icon: 'MyIcon4',
    color: '#cccccc',
    text: 'text4'
  }
];

然后,看评论:

class MyStaticWebPage extends React.Component {
  var buttonTypes = [LeftButton, CenterButton, RightButton];
  render() {
    var rows = [];
    var children = [];
    for (var i = 0; i < icons.length; i++) {
      // x will be 0, 1, or 2
      var x = i % 3;
      // Get the button type to use
      var buttonType = buttonTypes[x];
      // Create the button using `createElement`
      children.push(React.createElement(buttonType, icons[i]);
      // If this is the last button of three, add these in a container
      // and get a new array for children
      if (x == 2) {
        rows.push(<IconContainer>{children}</IconContianer>);
        children = [];
      }
    }
    // Handle any remaining children
    if (children.length) {
      rows.push(<IconContainer>{children}</IconContianer>);
    }
    return (
      <TopContainer>
        {rows}
      </TopContainer>
    );
  }
}

正如其他答案中所指出的那样 - 可以通过map函数来实现循环要动态显示它们,您可能希望查看flexbox并在 css 中使用它们。

一种可能的写作方式是这样的:

var buttonTypes = [LeftButton, CenterButton, RightButton];

let table = [];
arr.forEach((el, i) => {

  let Component = buttonTypes[i%3];
  rows.push(
    <Component
      Icon={el.icon}
      text={el.text}
      color={el.color}
    />
  )

  if(i%3 == 2) {
    table.push( <IconListContainer> {rows} </IconListContainer> )
    rows = [];
  }
})

if (rows.length) {
  table.push( <IconListContainer> {rows} </IconListContainer> );
}

return (
  <TopContainer>
    {table}
  </TopContainer>
);