渲染在有条件的for循环中反应

时间:2018-09-17 07:40:51

标签: javascript reactjs

我的网页上有静态信息。

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数组中。

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

如何通过现实的反应代码来解决这个问题?

5 个答案:

答案 0 :(得分:1)

我想您是在问如何确保使用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>
    );
  }
}

答案 1 :(得分:1)

鉴于您有一个平面数组,但要以三行的形式呈现它,您应该做的第一件事就是对数组进行分块。 Lodash为此提供了一种方法,或者您可以对数组进行足够简单的reduce。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:-1)

您可以尝试这样的事情。

const 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 {

  const menu = [
    ({ icon, color, text }) => (<LeftButton Icon={icon} color={color} text={text} />),
    ({ icon, color, text }) => (<CenterButton Icon={icon} color={color} text={text} />),
    ({ icon, color, text }) => (<RightButton Icon={icon} color={color} text={text} />)
  ];

  render() {
    return (
      <TopContainer>
        <IconListContainer>
          {icons && icons.map((icon, i) => menu[i % 3](icon))}
        </IconListContainer>
      </TopContainer>
    );
  }
}