Попытка условного отображения css для чередующихся элементов в массиве с useState в React с MUI

#reactjs #material-ui #react-hooks #conditional-statements #use-state

#reactjs #материал-пользовательский интерфейс #реагирующие хуки #условные операторы #use-state

Вопрос:

У меня есть объект arrays, который я отображаю поверх вызываемого featuredProj , и для альтернативных элементов я хочу, чтобы CSS отображался условно, чтобы не повторять так много кода. Используя useState в handleSide функции, я получаю ошибку too many rerenders . Как я могу это решить, или есть лучшее решение для рендеринга jsx при отображении по массиву объектов.

 const useStyles = makeStyles(() => ({
  title: {
    textAlign: (side) => (side ? "right" : "left"),
  },
}));

const FeaturedProjects = () => {
  const [side, setSide] = useState(true);
  const classes = useStyles(side);

  const handleSide = (project, index) => {
    if (index === 0 || index % 2 === 0) {

// I tried setSide(false), setSide(prev => !prev)
        
      return (
        <Grid Container key={index}>
              <Typography className={classes.title}>{project.title}</Typography>
        </Grid>
      );
    } else {
      return (
        <Grid Container key={index}>
              <Typography className={classes.title}>{project.title}</Typography>
        </Grid>
      );
    }
  };

  return (
    <Container>
      {featuredProj.map((proj, ind) => (
        <Reveal duration="2000" effect="fadeInUp">
          {handleSide(proj, ind)}
        </Reveal>
      ))}
    </Container>
  );
};
  

Заранее спасибо за любую помощь!

Комментарии:

1. Эй, @HoangDinh, вы возвращаете то же значение внутри вашего if и else условия.

2. Ах, извините @bertdida, я убирал код для публикации этого вопроса, чтобы его было легче читать, я убрал слишком много. По сути, значение else должно возвращать элементы jsx в другом порядке, а также иметь разные значения css.

Ответ №1:

Вы не можете вызвать setState() метод рендеринга внутри. setState() вызовет повторный рендеринг, который снова вызывает метод render, который приводит к другому setState() .. вы поняли идею.

Если вы хотите, чтобы это работало, вам нужно создать отдельный компонент с side реквизитами и передать его в качестве аргумента вашему стилевому хукуку.

 const FeaturedProjects = () => {
  const classes = useStyles(side);

  return (
    <Container>
      {featuredProj.map((proj, ind) => (
        <FeaturedProjectItem
          key={index}
          project={proj}
          side={index === 0 || index % 2 === 0}
        />
      ))}
    </Container>
  );
};

const useStyles = makeStyles({
  title: {
    textAlign: (side) => (side ? "right" : "left"),
  },
});
const FeaturedProjectItem = ({ side, project }) => {
  const classes = useStyles(side);

  return (
    <Reveal duration="2000" effect="fadeInUp">
      <Grid Container>
        <Typography className={classes.title}>{project.title}</Typography>
      </Grid>
    </Reveal>
  );
};
  

Комментарии:

1. Спасибо за ответ @NearHuscarl, я пытался избежать написания нескольких классов, чтобы иметь меньше строк кода.

2. Я обновил свой ответ относительно вашей озабоченности @HoangDinh

3. это выглядит как действительно хорошее решение, также достигает моей цели сделать его более модульным! Я попробую реализовать это, спасибо!