Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有“a”这样的东西吗;“正确”;用React钩子和Typescript定义状态的方法?_Javascript_Reactjs_Typescript_React Hooks - Fatal编程技术网

Javascript 有“a”这样的东西吗;“正确”;用React钩子和Typescript定义状态的方法?

Javascript 有“a”这样的东西吗;“正确”;用React钩子和Typescript定义状态的方法?,javascript,reactjs,typescript,react-hooks,Javascript,Reactjs,Typescript,React Hooks,我和React一起工作了一段时间,昨天我在一个基于Typescript的项目中被钩子弄湿了脚。重构之前,类的状态如下: interface INavItemProps { route: IRoute; } interface INavItemState { toggleStateOpen: boolean } class NavItem extends Component<INavItemProps, INavItemState> { constructor() {

我和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 });
  };

  ...
}
VITEMPROPS中的接口{ 路线:IRoute ;; } 接口无效状态{ toggleStateOpen:布尔值 } 类NavItem扩展组件{ 构造函数(){ this.state={toggleStateOpen:false}; } public handleClick=(元素:React.MouseEvent)=>{ 常量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);
  };

  ...
}
VITEMPROPS中的接口{ 路线:IRoute ;; } const NavItem:React.FunctionComponent=props=>{ const[toggleState,setToggleState]=useState(false); const{route}=props; 常量handleClick=(元素:React.MouseEvent)=>{ const newState=!toggleState; setToggleState(新闻状态); }; ... } 但我也测试了这个:

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});
  };
  ...
}
VITEMPROPS中的接口{ 路线:IRoute ;; } 接口无效状态{ toggleStateOpen:布尔值 } const NavItem:React.FunctionComponent=props=>{ const[state,setToggleState]=useState({toggleStateOpen:false}); const{route}=props; 常量handleClick=(元素:React.MouseEvent)=>{ const newState=!state.toggleStateOpen; setToggleState({toggleStateOpen:newState}); }; ... }
在这种情况下,有没有一种正确的方式来定义国家?或者我应该为状态的每个部分调用更多的钩子吗?

useState
hook允许您定义任何类型的状态,如对象、数组、数字、字符串、布尔值等。您需要知道的是,钩子更新程序不会将状态合并到自己的unline setState上,因此,如果您要维护一个数组或一个对象,并且只将要更新的值传递给更新程序,那么它实际上会导致其他状态丢失

通常情况下,最好使用多个钩子,而不是使用带有一个
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];
}
或者,如果状态/状态更新需要更复杂,并且需要将处理程序传递给组件,我建议使用
useReducer
hook,因为您有多个逻辑来更新状态,并且可以使用复杂的状态(如嵌套对象)和选择性地为更新编写逻辑