#reactjs #redux #react-redux
#reactjs #redux #реагировать-redux
Вопрос:
Я пытаюсь концептуализировать redux и его работу, и после некоторого тестирования я кое-что заметил. Я хотел бы привести этот пример
допустим, у меня есть один редуктор (логическая переменная). на основе этой переменной выполняется следующий код.
редуктор
const initState = { isLoggedIn: false };
const isLoggedInReducer = (state = initState, action) => {
switch (action.type) {
case "LOG_IN":
return { ...state,isLoggedIn: true };
case "LOG_OUT":
return { ...state,isLoggedIn: false };
default:
return state;
}
};
export default isLoggedInReducer;
Экшен
export const logIn = () => {
return {
type:'LOG_IN'
}
}
export const logOut = () => {
return {
type:'LOG_OUT'
}
}
index.js
<Provider store={createStore(isLoggedInReducer)}>
<Router>
<Switch>
<Route path="/" exact>
<AppScreen />
</Route>
<Route path="/auth">
<AuthScreen />
</Route>
<Route path="*">
<NotFoundScreen />
</Route>
</Switch>
</Router>
</Provider>
итак, мое приложение сначала направляет пользователя к компоненту под названием «Главный экран», который выглядит следующим образом
const AppScreen = () => {
let isLoggedIn = useSelector((state) => state.isLoggedIn);
if (isLoggedIn)
return (
<>
<button onClick={() => dispatch(logOut())}>unauthenticate</button>
<NavBar />
<Content />
<BottomBar />
</>
);
else{
return (
<>
<Redirect to="/auth" push />
</>
);
}
};
таким образом, если состояние редуктора имеет значение TRUE, отображается моя панель навигации и прочее, в противном случае пользователь перенаправляется на «authScreen», который выглядит следующим образом
const AuthScreen = () => {
let isLoggedIn = useSelector((state) => state.isLoggedIn);
const dispatch = useDispatch();
return isLoggedIn ? (
<>
<Redirect to="/" push />
</>
) : (
<>
<h1> auth is {isLoggedIn?"true":"false"}</h1>
<button onClick={() => dispatch(logIn())}>authenticate</button>
</>
);
};
Это создает настройку, в которой «authScreen» может переключить редуктор на TRUE, и он повторно визуализирует и обнаруживает, что reducer имеет значение TRUE, поэтому он отображает «главный экран». Наоборот для «главного экрана»
Теперь, какие компоненты на самом деле повторно визуализируются? Если я помещу свою кнопку аутентификации в «панель навигации» вместо этого как аналог «панели навигации», будет ли она повторно отображать «панель навигации» или «Главный экран»?
Как redux вычисляет, какой компонент нужно повторно визуализировать при изменении состояния? Как вписывается useSelector, когда я даже не использовал «connect».
Использование перехватов с помощью redux сделало это очень запутанным. Прошу прощения, если мое объяснение трудно понять. Код действительно работает, я просто не знаю как. Любая информация приветствуется!
Ответ №1:
Использование Redux с пользовательским интерфейсом всегда выполняет одни и те же основные шаги:
- Визуализация компонентов с использованием начального состояния
- Звоните
store.subscribe()
, чтобы получать уведомления о выполнении действий - Позвоните
store.getState()
, чтобы прочитать последние данные - Различайте старые и новые значения, необходимые этому компоненту, чтобы увидеть, действительно ли что-то изменилось. Если нет, то компоненту не нужно ничего делать
- Обновите пользовательский интерфейс с помощью последних данных
React-Redux делает это для вас внутренне.
Итак, useSelector
решает, следует ли повторно отображать компонент на основе любых данных, которые вы возвращаете в своих функциях селектора:
Если возвращаемое значение селектора изменяется после отправки действия, useSelector
это заставляет этот компонент повторно визуализировать. Оттуда запускается нормальное поведение рендеринга React, и все дочерние компоненты повторно визуализируются по умолчанию.
Пожалуйста, прочтите мой пост об истории и реализации React-Redux и расскажите о глубоком погружении в React-Redux для получения подробной информации о том, как React-Redux на самом деле реализует это поведение.
Комментарии:
1. Если я перемещу вызов useSelector внутри дочернего компонента некоторого компонента X, заставит ли он родительский X повторно визуализировать? Потому что это то, что происходит с моим кодом (более конкретно, из приведенного выше примера, кнопка, находящаяся в компоненте appScreen при перемещении на панель навигации, которая является дочерним элементом appScreen, по-прежнему вызывает повторную визуализацию appSceen вместо панели навигации)
2. Нет. Как и все перехваты,
useSelector
напрямую влияет только на компонент, внутри которого он находится. Но, как я уже сказал, React всегда рекурсивно перерисовывается по умолчанию, поэтому любые компоненты внутри него также будут перерисовываться.