Reputation: 131
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.
What will the custom hook look like?
Upvotes: 0
Views: 1349
Reputation: 2178
You can declare all your state/hooks logic in a function and export it to your component:
Example: For your login component you can extract your logic to a file, let's call it 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
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;
Upvotes: 1
Reputation: 181
You can create a new component with the same code, the difference is in the title and header from AuthLayout
<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
Upvotes: 0