如何在React中将对象从上到下渲染?

3

基本上我有一个像这样的对象列表:

const objects = [{name: 'some name', count: 'how many of that name'}, ...]

我想要像这样渲染它们:

        {objects.map((item) => (
            <Grid item key={item.name} xs={2} style={styles.count}>
                <Typography
                    key={item.name}
                    align="right"
                    component="h1">
                    {`${item.name}: ${item.count}`}
                </Typography>
            </Grid>
        ))}

正如你所想象的那样,这个结果是这样的。
name 1: 4   name 2: 4    name 3: 4
name 4: 4   name 4: 4

但是我需要的是这样的东西:
name 1: 4   name 3: 4    name 5: 4
name 2: 4   name 4: 4

请看这个链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Columns - Manish Sencha
3个回答

2
请查看 React MUI Grid-auto-flow,并按照以下方式调整您的代码并为父容器添加样式:
<Box
  sx={{
    display: 'grid',
    gridAutoFlow: 'column',
    gridTemplateRows: 'repeat(2, 1fr)',
    gap: 1,
  }}
>
  <Item>1</Item>
  <Item>2</Item>
  <Item>3</Item>
  <Item>4</Item>
  <Item>5</Item>
</Box>

最终结果应该像这样

result


(注意:已翻译,保留HTML标签)

你的答案还有待改进!如果项目数组的长度发生变化,它将无法正常工作。我已经编辑了你的答案,请查看这里 - Abbas Bagheri
1
很好,但这真的取决于用户想要多少行或列,如果我们想要固定两行,那么回答的代码将完美地自动对齐所有项在两行中,并且列会按需要自动计算。 可通过gridTemplateRows: 'repeat(numberOfRowsFixed, 1fr)'来控制固定行数... 详情请查看此处 - Hamza Mushtaq
你的答案很好,如果需要的话我将从现在开始使用它。 - Abbas Bagheri

0

我没有关于你问题的 css 技巧,但是我有一个 js 技巧,它可能会帮到你:

const items = [
  { name: 1, count: 5 },
  { name: 2, count: 5 },
  { name: 3, count: 5 },
  { name: 4, count: 5 },
  { name: 5, count: 5 },
  { name: 6, count: 5 },
  { name: 7, count: 5 }
  ....
];

function getColumns() {
  //get window width;
  const windowWidth = window.innerWidth;
  console.log(windowWidth);
  let columnsNumber = 3;

  //responsive on window width
  if (windowWidth < 400) {
    columnsNumber = 2;
  }

  const columns = new Array(columnsNumber);

  items.forEach((item, index) => {
    var columnNumber = Math.floor(index / columns.length);
    if (columns[columnNumber] === undefined) {
      columns[columnNumber] = [item];
    } else {
      columns[columnNumber].push(item);
    }
    console.log(columns);
  });
  return columns;
}

export default function App() {
  const [columns, setColumns] = useState(getColumns());
  useEffect(() => {
    window.addEventListener("resize", () => {
      setColumns(getColumns());
    });
  }, []);
  if (!columns) {
    return <h1>Loading</h1>;
  }

  console.log(columns);

  return (
    <Grid container>
      {columns.map((column, index) => (
        <Grid item key={index} xs={12/columns.length}>
          <Column items={column} />
        </Grid>
      ))}
    </Grid>
  );
}

function Column({ items }) {
  return (
    <>
      <Grid container>
        {items.map((item, index) => (
          <Grid item key={item.name} xs={12}>
            <Typography key={item.name} align="right" component="h1">
              {`${item.name}: ${item.count}`}
            </Typography>
          </Grid>
        ))}
      </Grid>
    </>
  );
}

代码的结果是:

enter image description here

你可以在 codesandbox上看到domo


0

修改您的代码,使用一个包含多行、每行三列的Grid容器

import { Grid, Typography } from '@material-ui/core';

const objects = [{name: 'some name', count: 'how many of that name'}, ...];

const rows = [];
let currentRow = [];
for (let i = 0; i < objects.length; i++) {
  currentRow.push(objects[i]);
  if (currentRow.length === 3 || i === objects.length - 1) {
    rows.push(currentRow);
    currentRow = [];
  }
}

return (
  <Grid container spacing={2} direction="column">
    {rows.map((row, rowIndex) => (
      <Grid item container key={rowIndex} spacing={2} direction="row">
        {row.map((item, itemIndex) => (
          <Grid item key={itemIndex} xs={4} style={styles.count}>
            <Typography align="right" component="h1">
              {`${item.name}: ${item.count}`}
            </Typography>
          </Grid>
        ))}
      </Grid>
    ))}
  </Grid>
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接