Есть ли такая вещь, как «правильный» способ определения состояния с помощью React-хуков и Typescript? - PullRequest
0 голосов
/ 19 февраля 2019

Я работаю с React некоторое время, а вчера я промок от хуков в проекте на основе Typescript.До рефакторинга у класса было такое состояние:

interface INavItemProps {
  route: IRoute;
}

interface INavItemState {
  toggleStateOpen: boolean
}

class NavItem extends Component<INavItemProps, INavItemState> {
  constructor() {
    this.state = { toggleStateOpen: false };
  }

  public handleClick = (element: React.MouseEvent<HTMLElement>) => {
    const toggleState = !this.state.toggleStateOpen;
    this.setState({ toggleStateOpen: toggleState });
  };

  ...
}

Теперь, когда рефакторинг превратился в функциональный компонент, я начал с этого

interface INavItemProps {
  route: IRoute;
}

const NavItem: React.FunctionComponent<INavItemProps> = props => {
  const [toggleState, setToggleState] = useState<boolean>(false);
  const { route } = props;

  const handleClick = (element: React.MouseEvent<HTMLElement>) => {
    const newState = !toggleState;
    setToggleState(newState);
  };

  ...
}

Но затем я также протестировал это:

interface INavItemProps {
  route: IRoute;
}

interface INavItemState {
  toggleStateOpen: boolean
}

const NavItem: React.FunctionComponent<INavItemProps> = props => {
  const [state, setToggleState] = useState<INavItemState>({toggleStateOpen: false});
  const { route } = props;

  const handleClick = (element: React.MouseEvent<HTMLElement>) => {
    const newState = !state.toggleStateOpen;
    setToggleState({toggleStateOpen: newState});
  };
  ...
}

Существует ли такая вещь, как правильный способ определения состояния в подобных случаях?Или мне просто нужно вызывать больше хуков для каждого среза состояния?

1 Ответ

0 голосов
/ 19 февраля 2019

useState hook позволяет вам определять любой тип состояния, например, Object, Array, Number, String, Boolean и т.д.таким образом, если вы поддерживаете массив или объект и передаете обновителю только значение, которое будет обновлено, это, по сути, приведет к потере других ваших состояний.

Чаще всего это может быть лучшеиспользуйте несколько хуков вместо использования объекта с одним хуком useState или, если хотите, вы можете написать свой собственный хук, который объединяет значения типа

const useMergerHook = (init) => {
   const [state, setState] = useState(init);
   const updater = (newState) => {
       if (Array.isArray(init)) {
          setState(prv => ([
             ...prv,
             ...newState
          ]))
       } else if(typeof init === 'object' && init !== null) {
          setState(prv => ({
            ...prv,
            ...newState
          }))
       } else {
          setState(newState);
       }

   }
   return [state, updater];
}

, или если обновления состояния / состояния должны быть болееcomplex и обработчик необходимо передать компоненту, я бы рекомендовал использовать хук useReducer, поскольку у вас есть несколько логик для обновления состояния и вы можете использовать сложные состояния, такие как вложенные объекты и логика записи для обновления выборочно

...