简体   繁体   English

如何使用 react 自定义钩子使代码可重用

[英]How do I use react custom hooks to make code reusable

I have two components similar like below:我有两个类似的组件,如下所示:

const Login = props => {
    let loading;
    const dispatch = useDispatch();
    const [notification, setNotification] = React.useState('');
    const [hasNotification, setHasNotification] = React.useState('');
    const [isLoading, setIsLoading] = React.useState(false);
    const {status, message} = useSelector(state => state.LoginReducer);
    const { register, handleSubmit, formState, errors } = useForm({
        mode: "onChange"
    });
    const onSubmit = data => {
        setIsLoading(true);
        dispatch(loginStart(data));
    };
    React.useEffect(() => {
        setIsLoading(false);
        if (status === 422) {
            setNotification(message);
            setHasNotification('ERROR');
            return;
        }
        if (status === 200) {
            setNotification(message);
            setHasNotification('SUCCESS');
        }
    }, [status, message]);
    React.useEffect(() => {
        console.log('componentDidMount');
        return () => {
            setNotification('');
            setHasNotification('');
        };
    }, []);
    return (
        <AuthLayout title={'Login'} header={'Welcome back, Sign in'} hasNotification={hasNotification} notification={notification}>
        </AuthLayout>
    )
}
export default Login;

I also have another component with similar functionality as above我还有另一个与上述功能相似的组件

const Signup = props => {
    let loading;
    const dispatch = useDispatch();
    const [notification, setNotification] = React.useState('');
    const [hasNotification, setHasNotification] = React.useState('');
    const [isLoading, setIsLoading] = React.useState(false);
    const {status, message} = useSelector(state => state.SignupReducer);
    const { register, handleSubmit, formState, errors } = useForm({
        mode: "onChange"
    });
    const onSubmit = data => {
        setIsLoading(true);
        dispatch(signupStart(data));
    };
    React.useEffect(() => {
        setIsLoading(false);
        if (status === 422) {
            setNotification(message);
            setHasNotification('ERROR');
            return;
        }
        if (status === 200) {
            setNotification(message);
            setHasNotification('SUCCESS');
        }
    }, [status, message]);
    React.useEffect(() => {
        console.log('componentDidMount');
        return () => {
            setNotification('');
            setHasNotification('');
        };
    }, []);
    return (
        <AuthLayout title={'Signup'} header={'Discover a new way to do amazing work'} hasNotification={hasNotification} notification={notification}>
        </AuthLayout>
    )
}
export default Signup;

I read about custom hooks but just curious how I can move the state and logic to a separate custom hook function since they have similar structure and functionalities.我阅读了自定义挂钩,但只是好奇如何将 state 和逻辑移动到单独的自定义挂钩 function,因为它们具有相似的结构和功能。

What will the custom hook look like?自定义钩子会是什么样子?

You can declare all your state/hooks logic in a function and export it to your component:您可以在 function 中声明所有状态/挂钩逻辑并将其导出到您的组件:

Example: For your login component you can extract your logic to a file, let's call it useLogin.js示例:对于您的登录组件,您可以将您的逻辑提取到一个文件中,我们称之为useLogin.js

useLogin.js : useLogin.js

export default () => {
    const [notification, setNotification] = React.useState('');
    const [hasNotification, setHasNotification] = React.useState('');
    const [isLoading, setIsLoading] = React.useState(false);
    const { register, handleSubmit, formState, errors } = useForm({
        mode: "onChange"
    });
    React.useEffect(() => {
        setIsLoading(false);
        if (status === 422) {
            setNotification(message);
            setHasNotification('ERROR');
            return;
        }
        if (status === 200) {
            setNotification(message);
            setHasNotification('SUCCESS');
        }
    }, [status, message]);
    React.useEffect(() => {
        console.log('componentDidMount');
        return () => {
            setNotification('');
            setHasNotification('');
        };
    }, []);
   return [notification, hasNotification, setIsLoading]; //return all variable and functions that you need in your component
}

And in Login you should import your function and use it在登录中,您应该导入您的 function 并使用它

import useLogin from './useLogin'; // first import useLogin function
const Login = props => {
    let loading;
    const dispatch = useDispatch();
    const {status, message} = useSelector(state => state.LoginReducer);
    const [notification, hasNotification, setIsLoading] = useLogin(); // call useLogin and get notification and hasNotification objects
    const onSubmit = data => {
        setIsLoading(true);
        dispatch(loginStart(data));
    };
    return (
        <AuthLayout title={'Login'} header={'Welcome back, Sign in'} hasNotification={hasNotification} notification={notification}>
        </AuthLayout>
    )
}
export default Login;

Same thing to Signup component与注册组件相同

import useLogin from './useLogin';
const Signup = props => {
    let loading;
    const dispatch = useDispatch();
    const {status, message} = useSelector(state => state.SignupReducer);
    const [notification, hasNotification, setIsLoading] = useLogin();
    const onSubmit = data => {
        setIsLoading(true);
        dispatch(signupStart(data));
    };
    return (
        <AuthLayout title={'Signup'} header={'Discover a new way to do amazing work'} hasNotification={hasNotification} notification={notification}>
        </AuthLayout>
    )
}
export default Signup;

Hope the idea was clear;希望这个想法很清楚;

You can create a new component with the same code, the difference is in the title and header from AuthLayout您可以使用相同的代码创建一个新组件,不同之处在于标题和来自 AuthLayout 的 header

<AuthLayout title={props.title} header={props.header} hasNotification={hasNotification} notification={notification}></AuthLayout>

Login登录

const Login = props => {
    return (
        <newComponent title={'Login'} header={'Welcome back, Sign in'} />
    )
}
export default Login;

SignUp报名

const SignUp = props => {
    return (
        <newComponent title={'SignUp'} header={'Discover a new way to do amazing work'} />
    )
}
export default SignUp;

I called newComponent, the component that you will create我调用了 newComponent,您将创建的组件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM