Слишком много повторных рендеров. При установке состояния - PullRequest
1 голос
/ 12 июля 2020

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

  1. Через нижнюю навигацию - этот работает нормально
  2. Через кнопки на домашней странице

Попытка setState основан на параметрах, которые поступают через домашнюю страницу, но выдает ошибку Too many re-renders. Ниже приведен код, который у меня в настоящее время есть для него.

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

export default function CategoryList(props: Props) {
  let { params } = useRoute<StackRouteProp<'Home'>>()

  const [currentCategory, setCategory] = useState({categories: Categories[0]});

  if (params) {
    setCategory({categories: params.categories})
  }
}

Ответы [ 2 ]

2 голосов
/ 12 июля 2020

Вы также можете использовать useEffect с useRef:

export default function CategoryList(props: Props) {
  let { params } = useRoute<StackRouteProp<'Home'>>()

  const [currentCategory, setCategory] = useState({categories: Categories[0]});
  const canSet = useRef(true)

  useEffect(() => {
    if (params && canSet.current) {
      setCategory({ categories: params.categories })
      canSet.current = false
    } else {
      canSet.current = true
    }
  }, [params])
1 голос
/ 12 июля 2020

Каждый раз, когда вы вызываете setCategory, компонент повторно визуализируется. Затем каждый раз, когда вы визуализируете компонент, если params существует, он снова будет вызывать setCategory, что вызовет другой рендеринг, который снова вызовет setCategory и так далее, пока он не достигнет предела визуализации React.

Один из возможных способов обойти это - добавить логическое значение для установки после первого раза, что предотвратит его попадание внутрь блока if во второй раз:

const [currentCategory, setCategory] = useState({categories: Categories[0]});
const [hasParamsCategory, setParamsCategory] = useState(false);

if (params && !hasParamsCategory) {
  setCategory({categories: params.categories});
  setParamsCategory(true);
}

Это все еще не идеален, потому что в целом не рекомендуется напрямую вызывать функции изменения состояния во время рендеринга, но это послужит быстрым и грязным обходным путем.

...