Установка состояния внутри компонента в ReactJS

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть этот компонент в моем приложении react js:

 import React, { useState } from "react";
import Select, { components, DropdownIndicatorProps } from "react-select";
import { ColourOption, colourOptions } from "./docs/data";

const Component = () => {
  const [state, setState] = useState();
  console.log(state);
  const DropdownIndicator = (props) => {
    const { menuIsOpen } = props.selectProps;
    setState(menuIsOpen);
    return (
      <components.DropdownIndicator {...props}>12</components.DropdownIndicator>
    );
  };

  return (
    <Select
      closeMenuOnSelect={false}
      components={{ DropdownIndicator }}
      defaultValue={[colourOptions[4], colourOptions[5]]}
      isMulti
      options={colourOptions}
    />
  );
};

export default Component; 

В компоненте DropDownIndicator я устанавливаю состояние:

 const {
  menuIsOpen
} = props.selectProps;
setState(menuIsOpen); 

Устанавливая состояние в этом месте, я получаю следующее предупреждение: Warning: Cannot update a component (Component) while rendering a different component (DropdownIndicator). To locate the bad setState() call inside DropdownIndicator .
Вопрос: Как я могу исправить это предупреждение и заставить его исчезнуть?
демонстрация: https://codesandbox.io/s/codesandboxer-example-forked-97sx0?file=/example.tsx:0-724

Ответ №1:

Вы должны вызвать setState внутри useEffect

 const DropdownIndicator = (props) => {
    const { menuIsOpen } = props.selectProps;

    useEffect(() => {
        setState(menuIsOpen);
      });

    return (
      <components.DropdownIndicator {...props}>12</components.DropdownIndicator>
    );
  };
 

Подробнее Что делает useEffect ? Используя этот хук, вы сообщаете React, что ваш компонент должен что-то сделать после рендеринга. об использовании эффекта

Если ваш setState зависит от menuIsOpen . Передать useEffect как зависимость.

  const DropdownIndicator = (props) => {
    const { menuIsOpen } = props.selectProps;

      useEffect(() => {
        setState(menuIsOpen);
      },[menuIsOpen]);

    return (
      <components.DropdownIndicator {...props}>12</components.DropdownIndicator>
    );
  };
 

Полное решение на CodeSandbox

Ответ №2:

Просто отметьте значение useState по умолчанию как false

 const [state, setState] = useState(false);
 

похоже, когда вы делаете setState(menuIsOpen); это в первый раз, его значение равно undefined и DropdownIndicator еще не завершено при первом рендеринге,

[Гипотеза] Должен быть какой-то код с реактом.Компонент согласно трассировке стека, основанный на проверке undefined / null. Но при задании initialState ошибка не возникает.