Я изучаю React Hook и useEffect
, но могу не понять ключевой момент его правильного использования.
У меня следующий сценарий:
- Если пользователь переключает раскрывающийся список, проверяет наличие флага
isAnyChange
из глобального состояния, есть ли какие-либо обновления на текущей странице. - Если изменений нет, будет go вперед и перенаправит на следующую страницу,
- Если есть какие-либо изменения, отобразится диалоговое окно подтверждения.
Затем внутри диалогового окна подтверждения будут 2 кнопки:
- 4.1 одна спрашивает для сохранения, проверки валидации и перенаправления
- 4.2 запрашивается не сохранять и перенаправлять.
Я включаю вышеуказанный лог c с использованием другого useEffect
, но я не уверен, правильно ли я поступаю, так как он выглядит подключенным ко мне и усложняющим вещи, тогда как лучше всего разложить мои функции? Я делаю правильный дизайн, используя эти local state flag
для запуска разных useEffect
? Я не мог придумать лучшего способа ...
const pageComponent = props => {
const [isSelectChange, setIsSelectChange] = useState(false);
const [canRedirect, setCanRedirect] = useState(false);
const [isSaveCompleted, setIsSaveCompleted] = useState(false);
const anyChange = useSelector(state => return state.anyChange;);
const anyValidError = useSelector(state => return state.anyValidError;);
// step 1. dropdown change to change local state and trigger useEffect in step 2
const selectChange = () => {
setIsSelectChange(true);
}
// step 2. state isSelectChange to trigger step 3 howConfirmDialog or useEffect in step 6
useEffect(() => {
if (isSelectChange) {
if (anyChange) { showConfirmDialog(); }
else { setCanRedirect(); }
// should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing
// setIsSelectChange(false);
}
return () {
// clean up to reset the flag back to avoid looping here on isSelectChange, is it the right place to do it here?
setIsSelectChange(false);
}
}, [isSelectChange])
// step 3. dispatch a confirm dialog
const showConfirmDialog() => {
dispatch(openConfirmDialog(
dialog: <ConfirmDialog confirmhdlr={saveAndRedirect} cancelhdlr={cancelAndRedirect} />
);
}
// step 4.1 save and redirect
const saveAndRedirect = async () => {
await(savePage());
// this is to trigger another useEffect monitoring on isSaveCompleted flag
setIsSaveCompleted(true);
setCanRedirect(true);
}
// step 4.2 cancel and redirect
const cancelAndRedirect = () => {
setCanRedirect(true);
}
// step 5. state isSaveCompleted to trigger
useEffect(() => {
if (isSaveCompleted && !anyValidError) {
// this is to trigger another useEffect monitoring on "canRedirect"
setCanRedirect(true);
// should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing
// setIsSaveCompleted(false);
}
return () {
// clean up to reset the flag back to avoid looping here on isSaveCompleted flag, is it the right place to do it here?
setIsSaveCompleted(false);
}
}, [isSaveCompleted])
// step 6. state canRedirect to trigger redirect
useEffect(() => {
if (canRedirect) {
if (isSaveCompleted && !anyValidError) {
// this is to trigger another useEffect monitoring on "canRedirect"
setCanRedirect(true);
}
// should I placed it here? but this seems to trigger the same useEffect a second time even though no code is executing
// setCanRedirect(false);
}
return () {
// clean up to reset the flag back to avoid looping here on canRedirect flag, is it the right place to do it here?
setCanRedirect(false);
}
}, [canRedirect])
return (<select onChange={selectChange}>)
}
, как вы видите, у меня есть разные флаги для запуска разных useEffect
, я мог бы сделать их все в одной функции, тогда зачем использовать useEffect
здесь?