是否存在使用React钩子和Typescript定义状态的“正确”方法?

时间:2019-02-19 07:02:45

标签: javascript reactjs typescript react-hooks

我已经在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 :(得分:5)

b2[0]钩子允许您定义任何类型的状态,例如对象,数组,数字,字符串,布尔值等。您需要知道的是,钩子更新程序不会将其状态单独合并setState,因此,如果您维护数组或对象,并且仅将要更新的值传递给更新程序,则从根本上会导致其他状态丢失。

通常,最好使用多个钩子而不是使用带有一个a2[0]钩子的对象,或者如果您愿意,可以编写自己的自定义钩子来合并值,例如

useState

或者如果状态/状态更新需要更复杂并且需要将处理程序传递给组件,我建议您使用useState钩子,因为您有多种逻辑来更新状态并且可以利用诸如嵌套对象之类的复杂状态,并有选择地为更新编写逻辑