Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.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 如何重构我重复的代码并创建可共享的代码_Javascript_Reactjs_React Hooks_Refactoring - Fatal编程技术网

Javascript 如何重构我重复的代码并创建可共享的代码

Javascript 如何重构我重复的代码并创建可共享的代码,javascript,reactjs,react-hooks,refactoring,Javascript,Reactjs,React Hooks,Refactoring,我想重构我的代码,因为它是重复的,对我来说很难看,因为我把代码从一个文件复制到另一个需要相同逻辑的文件。有没有一种方法可以让我创建一个可共享的代码,例如,Vue中的mixin?我有一个想法,建立一个自定义钩子,将成为其他文件共享,或者如果你有任何建议,请帮助我,因为我是新的反应 顺便说一下,下面显示的代码正在运行。我用这个来注册、登录和忘记密码页面。 因此,它所做的是根据firebase的结果显示或显示带有消息和乐蒂动画的对话框。我使用redux工具包与firebase通信 这是我的密码 use

我想重构我的代码,因为它是重复的,对我来说很难看,因为我把代码从一个文件复制到另一个需要相同逻辑的文件。有没有一种方法可以让我创建一个可共享的代码,例如,Vue中的mixin?我有一个想法,建立一个自定义钩子,将成为其他文件共享,或者如果你有任何建议,请帮助我,因为我是新的反应

顺便说一下,下面显示的代码正在运行。我用这个来注册、登录和忘记密码页面。 因此,它所做的是根据firebase的结果显示或显示带有消息和乐蒂动画的对话框。我使用redux工具包与firebase通信

这是我的密码

useEffect(() => {
// check the status state and display the spinner and dialog
if (status === 'pending') {
  setVisibility(true);
} else if (status === 'success') {
  setVisibility(false);
  if (
    user === 'The password is invalid or the user does not have a password.'
  ) {

     setDialog({
      display: true,
      text: user,
      lottie: FailedAnimation,
    });
    setTimeout(() => {
      setDialog({
        display: false,
      });
    }, 3000);
  } else {
    setDialog({
      display: true,
      text: 'Redirecting homepage...',
      lottie: SignupSuccessAnimated,
    });
    setTimeout(() => {
      setDialog({
        display: false,
      });
    }, 3000);
  }
} else if (status === 'failed') {
  setVisibility(false);
  setDialog({
    display: true,
    text: 'Please try again...',
    lottie: FailedAnimation,
  });
  setTimeout(() => {
    setDialog({
      display: false,
    });
  }, 3000);
}  }, [status, history, user]);

这是该片段的回购协议

您可能希望将代码的各个部分抽象为它们自己的函数

您可以在整个代码中重复调用
setDialog()
函数,但这些函数可以抽象为它们自己整洁的函数,例如:

useEffect(() => {
// check the status state and display the spinner and dialog
if (status === 'pending') {
  setVisibility(true);
} else if (status === 'success') {
  setVisibility(false);
  if (
    user === 'The password is invalid or the user does not have a password.'
  ) {
    setFailedDialog();
  } else {
    setRedirectingDialog();
  }
} else if (status === 'failed') {
  setVisibility(false);
  setTryAgainDialog();
}  }, [status, history, user]);
您已将以下代码重复了三次:

setTimeout(() => {
    setDialog({
      display: false,
    });
  }, 3000);

相反,您可以将其封装到单个函数中,并在需要时调用它,而不是重复您自己的操作(编程中的大量禁忌)。

我没有使用自定义钩子的经验,但是您在这里有一个完整的身份验证钩子:

此外,我还可以看到另外两种解决方案:

  • 由于您的身份验证页面非常相似,也许您可以在
    AuthenticationPage
    组件中共享这些相似之处,通过道具传递不断变化的行为/内容。例如,要分派的操作以及作为子级的内部窗体:
  • 组件间重用行为的一种方法是创建高阶组件。但这在复杂性上更进一步:

  • 我会将
    状态
    管理提取到一个外部函数,然后根据它返回的内容进行操作

    如果
    状态改变或组件卸载,您还应该清除超时

    示例(未测试):


    嗨,谢谢你的回复。在这种情况下,这是定制挂钩吗?不客气。它不是一个定制的钩子,因为它在另一个钩子中使用,并且不能在钩子中使用钩子。它只是一个抽象出一些逻辑的函数。如果你需要在多个地方使用它,你可以从
    useffect
    块中创建一个自定义钩子。我应该为我的案例创建一个自定义钩子吗?将所有可重用逻辑(
    useffect
    useState
    ,等等)包装在一个自定义钩子中。您仍然可以将
    handleState
    函数保留在钩子之外,并在钩子中使用它。因为这是一个纯函数。
    // Outside the component
    const NO_PASSWORD = 'The password is invalid or the user does not have a password.';
    
    const handleState = (state, user) => {
      switch(state) {
        case 'pending':
          return { display: true };
          
        case 'success': {
          const display = false;
          
          return user === NO_PASSWORD 
            ? { display, text: user, lottie: FailedAnimation} 
            : { display, text: 'Redirecting homepage...', lottie: SignupSuccessAnimated} ;
        }
        
        case 'failed':
          return { display: false, text: 'Please try again...', lottie: FailedAnimation };
          
        default:
          throw new Error(`Invalid state: ${state}`);
      }
    }
    
    // Inside the component
    useEffect(() => {
      let timeout;
    
      const { display, text, lottie } = handleState(state, user); 
      
      if(text) {
        setDialog({ display, text, lottie });
    
        timeout = setTimeout(() => {
          setDialog({ display: false });
        }, 3000);
      }
      
      setVisibility(visibility);
      
      return () => {
        clearTimeout(timeout);
      };
    }, [status, user]);