【问题标题】:Reactjs Grid layout with defined number of columns具有定义列数的 Reactjs 网格布局
【发布时间】:2018-09-23 14:19:41
【问题描述】:

如何使用具有以下格式的 javascript 实现网格/卡片布局:

<div class='x'>
  <div class='y'></div>
  <div class='y'></div>
  <div class='y'></div>
</div>
<div class='x'>
  <div class='y'></div>
  <div class='y'></div>
  <div class='y'></div>
</div>

列容器的项目是通过像 FileList 组件中这样的数组映射来检索的:

data.files.map(file => (
  <FileItem
    key={file.id}
    file={file}
    refresh={() => refetch()}
  />
))

我可以在 FileItem 组件中传入&lt;div class='y'&gt;。 我只是不知道如何实现行容器的逻辑。

基本上我想要这个:

<div class='x'>
  <div class='y'>FileItem 1</div>
  <div class='y'>FileItem 2</div>
  <div class='y'>FileItem 3</div>
</div>
<div class='x'>
  <div class='y'>FileItem 4</div>
  <div class='y'>FileItem 5</div>
  <div class='y'>FileItem 6</div>
</div>

【问题讨论】:

  • 这只有在你事先将你的列表分成三个块然后遍历列表列表时才有可能。 loash chunk 这样做。但在大多数情况下,您不需要这个。最好只有一个容器,让元素自己浮到下一行。换句话说,对齐应该使用 css 而不是 html。

标签: javascript arrays reactjs layout grid


【解决方案1】:

一个可能的解决方案是使用 lodash 库中的 _chunk() 创建一个块列表,然后在其自己的容器中渲染每个块:

render() {
    const elements = [1, 2, 3, 4, 5, 6, 7, 8];
    const chunked = _chunk(elements, 3); // [[1, 2, 3], [4, 5, 6], [7, 8]]

    return(
        {chunked.map(chunk => (
            <div className="row" key="???">
                {chunk.map(elem => (
                    <div className="col" key="???" >{elem}</div>
                ))}
            </div>
        ))}
    );
}

这将产生以下标记:

<div class="row">
    <div class="col">1</div>
    <div class="col">2</div>
    <div class="col">3</div>
</div>
<div class="row">
    <div class="col">4</div>
    <div class="col">5</div>
    <div class="col">6</div>
</div>
<div class="row">
    <div class="col">7</div>
    <div class="col">8</div>
</div>

当你需要为每个行容器找到一个键时,这个问题就已经开始了,因为 react 期望相同类型的兄弟姐妹有一个唯一的键。

获得相同对齐的更好方法是只有一个容器,当行满时让元素自动浮动到下一个“行”中。这可以例如使用flexbox实现:

const numItemsPerRow = 3;

const containerStyle = { 
  display: "flex", 
  width: "600px", 
  flexWrap: "wrap" 
};

const itemStyle = {
  minWidth: `${100 / numItemsPerRow}%`,
  textAlign: "center",
  border: "1px solid black",
  boxSizing: "border-box"
};

const elements = [1, 2, 3, 4, 5, 6, 7, 8];

const Grid = () => (
  <div style={containerStyle}>
    {elements.map(elem => <div style={itemStyle}>{elem}</div>)}
  </div>
);

you can find a good tutorial on how to use flexbox here.

【讨论】:

  • 感谢您的回答。如果我想限制每行的项目数,我就必须使用百分比宽度,对吧?
  • @mowtheone 没错。每个项目的宽度为100% / number_of_items_per_row
  • @mowtheone 我创建了一个codesandbox example
  • 在项目和行之间设置间距的最简洁方法是什么?
  • @mowtheone 我改变了主意:)。最干净的解决方案是使用 css calc() 来计算最大宽度。查看我更新的代码框。
猜你喜欢
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
相关资源
最近更新 更多