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

Javascript 如何使用react自定义挂钩使代码可重用,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有两个类似的组件,如下所示: const Login = props => { let loading; const dispatch = useDispatch(); const [notification, setNotification] = React.useState(''); const [hasNotification, setHasNotification] = React.useState(''); const [isLoadin

我有两个类似的组件,如下所示:

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;
const Login=props=>{
让加载;
const dispatch=usedpatch();
const[notification,setNotification]=React.useState(“”);
const[hasNotification,setHasNotification]=React.useState(“”);
const[isLoading,setIsLoading]=React.useState(false);
const{status,message}=useSelector(state=>state.LoginReducer);
常量{register,handleSubmit,formState,errors}=useForm({
模式:“onChange”
});
const onSubmit=data=>{
设置加载(真);
调度(后勤启动(数据));
};
React.useffect(()=>{
设置加载(假);
如果(状态===422){
设置通知(消息);
setHasNotification(“错误”);
返回;
}
如果(状态===200){
设置通知(消息);
setHasNotification(“成功”);
}
},[状态、消息];
React.useffect(()=>{
log('componentDidMount');
return()=>{
设置通知(“”);
setHasNotification(“”);
};
}, []);
返回(
)
}
导出默认登录;
我还有另一个组件,功能与上面类似

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;

const Signup=props=>{
让加载;
const dispatch=usedpatch();
const[notification,setNotification]=React.useState(“”);
const[hasNotification,setHasNotification]=React.useState(“”);
const[isLoading,setIsLoading]=React.useState(false);
const{status,message}=useSelector(state=>state.SignupReducer);
常量{register,handleSubmit,formState,errors}=useForm({
模式:“onChange”
});
const onSubmit=data=>{
设置加载(真);
调度(signupStart(数据));
};
React.useffect(()=>{
设置加载(假);
如果(状态===422){
设置通知(消息);
setHasNotification(“错误”);
返回;
}
如果(状态===200){
设置通知(消息);
setHasNotification(“成功”);
}
},[状态、消息];
React.useffect(()=>{
log('componentDidMount');
return()=>{
设置通知(“”);
setHasNotification(“”);
};
}, []);
返回(
)
}
导出默认注册;
我读过关于定制钩子的书,但我只是好奇如何将状态和逻辑移动到一个单独的定制钩子函数,因为它们具有相似的结构和功能


自定义钩子看起来像什么?

您可以使用相同的代码创建一个新组件,不同之处在于AuthLayout的标题和标题

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

登录

const Login = props => {
    return (
        <newComponent title={'Login'} header={'Welcome back, Sign in'} />
    )
}
export default Login;
const Login=props=>{
返回(
)
}
导出默认登录;
注册

const SignUp = props => {
    return (
        <newComponent title={'SignUp'} header={'Discover a new way to do amazing work'} />
    )
}
export default SignUp;
const SignUp=props=>{
返回(
)
}
导出默认注册;

我调用了newComponent,您将创建的组件

您可以在函数中声明所有状态/挂钩逻辑并将其导出到您的组件:

例如:对于登录组件,您可以将逻辑提取到文件中,我们称之为
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
}
在登录时,您应该导入您的函数并使用它

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;
从“/useLogin”导入useLogin;//首次导入useLogin函数
const Login=props=>{
让加载;
const dispatch=usedpatch();
const{status,message}=useSelector(state=>state.LoginReducer);
const[notification,hasNotification,setIsLoading]=useLogin();//调用useLogin并获取notification和hasNotification对象
const onSubmit=data=>{
设置加载(真);
调度(后勤启动(数据));
};
返回(
)
}
导出默认登录;
注册组件也是一样

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;
从“/useLogin”导入useLogin;
const Signup=props=>{
让加载;
const dispatch=usedpatch();
const{status,message}=useSelector(state=>state.SignupReducer);
const[notification,hasNotification,setIsLoading]=useLogin();
const onSubmit=data=>{
设置加载(真);
调度(signupStart(数据));
};
返回(
)
}
导出默认注册;
希望思路清晰