javascript - 如何使用 react 自定义钩子使代码可重用
问题描述
我有两个类似的组件,如下所示:
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 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;
我阅读了自定义钩子,但只是好奇如何将状态和逻辑移动到单独的自定义钩子函数,因为它们具有相似的结构和功能。
自定义钩子会是什么样子?
解决方案
您可以在函数中声明所有状态/挂钩逻辑并将其导出到您的组件:
示例:对于您的登录组件,您可以将逻辑提取到文件中,我们称之为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;
与注册组件相同
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;
希望这个想法很清楚;
推荐阅读
- swift - 在 macOS 上的 WKWebView 中加载图像
- javascript - 当系列没有相同的时间值时,如何在工具提示中显示所有系列
- java - 用于无效输出的 AWS Lambda RequestHandler
- seo - 没有用户选择的规范的重复
- java - JavaFX:如何向 Canvas 的子类添加方法,允许将按钮添加到 cavas 本身?
- asp.net-web-api - 如何使用 Angular 7 和 webAPI 重置密码
- apache-flink - 如何根据内容写入不同的文件以在 Flink 中进行批处理?
- docker - Kibana UI 在 ElasticSearch 重启后总是显示状态页面
- php - Magento2 目录:图像:调整 mysql 大小
- react-native - React-Native :使用 componentDidMount 上的 ref 计算 FlatList 的 scrollToItem 并渲染它