render ()
Мы можем переосмыслить вопрос «рендерить или не рендерить» чуть-чуть.Метод визуализации будет всегда вызываться до обратных вызовов или методов жизненного цикла.Это справедливо, за исключением некоторых устаревших методов жизненного цикла .
, которые вскоре должны быть реализованы. Таким образом, ваш метод рендеринга (или функциональный компонент) должен обрабатывать все возможные состояния, включая состояния, которые ничего не требуютбыть оказанным.Либо это, либо работа по рендерингу ничего не может быть поднята до родительского компонента.Это разница между:
const Child = (props) => props.yes && <div>Hi</div>;
// ...
<Parent>
<Child yes={props.childYes} />
</Parent>
и
const Child = (props) => <div>Hi</div>;
// ...
<Parent>
{props.childYes && <Child />}
</Parent>
Решение о том, какой из них использовать, является ситуативным.
Крючки
Есть способыиспользования хуков для решения тех же проблем, которые делают HOC.Я бы начал с того, что предлагает HOC;способ доступа к пользовательским данным о состоянии приложения и перенаправление на /signin
, когда данные означают недопустимый сеанс.Мы можем снабдить обе эти вещи хуками.
import { useSelector } from "react-redux";
const mapState = state => ({
isAuthenticated: state.currentUser.isAuthenticated
});
const MySecurePage = props => {
const { isAuthenticated } = useSelector(mapState);
useEffect(
() => {
if (!isAuthenticated) {
history.push("/signin");
}
},
[isAuthenticated]
);
return isAuthenticated && <MyPage {...props} />;
};
Пара вещей, происходящих в примере выше.Мы используем хук useSelector
из react-redux
для доступа к состоянию, как мы это делали ранее, используя connect
, только с гораздо меньшим количеством кода.
Мы также используем полученное нами значениеот useSelector
для условного срабатывания побочного эффекта с помощью крючка useEffect
.По умолчанию обратный вызов, который мы передаем useEffect
, вызывается после каждого рендера.Но здесь мы также передаем массив зависимостей, который сообщает React, что мы хотим, чтобы эффект срабатывал только при изменении зависимости (в дополнение к первому рендеру, который всегда запускает эффект).Таким образом, мы будем перенаправлены, когда isAuthenticated
начнет false или станет false.
Хотя в этом примере используется определение компонента, он также работает как пользовательский хук:
const mapState = state => ({
isAuthenticated: state.currentUser.isAuthenticated
});
const useAuth = () => {
const { isAuthenticated } = useSelector(mapState);
useEffect(
() => {
if (!isAuthenticated) {
history.push("/signin");
}
},
[isAuthenticated]
);
return isAuthenticated;
};
const MySecurePage = (props) => {
return useAuth() && <MyPage {...props} />;
};
OneПоследнее, что вы можете задаться вопросом:
const AuthWrapper = (props) => useAuth() && props.children;
, чтобы сделать что-то вроде этого:
<AuthWrapper>
<Sensitive />
<View />
<Elements />
</AuthWrapper>
Вы можете решить, что последний примерподходить для вас, но я бы прочитал это , прежде чем принять решение.