#reactjs #react-redux #react-hooks
Вопрос:
Я получаю предупреждение в своем веб-приложении и прочитал много сообщений об этой проблеме. К сожалению, мне не удалось решить свою проблему, и я надеюсь, что у кого-нибудь может быть какой-нибудь совет. Из того, что я могу сказать, мне нужно найти способ отправки в магазин с эффектом использования. Но мои усилия до сих пор не увенчались успехом.
В предупреждении говорится:
index.js:1 Предупреждение: Не удается обновить компонент (
Connect(TabMenuComponent)
) при отображении другого компонента (ReactRedux.Consumer
). Чтобы найти неправильный вызов setState() внутриReactRedux.Consumer
, следуйте трассировке стека, как описано в https://reactjs.org/link/setstate-in-render
Трассировка стека далее указывает мне на этот файл. Он указывает на строку 30, которая является строкой магазина.отправка:
export const AuthRoute = ({ component: Component, roles, computedMatch, ignoreRedirection, ...rest }) => (
<Route exact {...rest} render={props => {
return <ReactReduxContext.Consumer>
{({ store }) => {
const user = store.getState().appData.user;
if (!user) {
auth.setRedirectUrl(window.location.pathname);
return <Redirect to={auth.loginUrl} />;
}
const redirectUrl = auth.getRedirectUrl();
if (redirectUrl amp;amp; !ignoreRedirection) {
auth.removeRedirectUrl();
return <Redirect to={redirectUrl} />;
}
if (roles amp;amp; roles.length amp;amp; !roles.some(neededRole => user.roles.some(userRole => userRole === neededRole))) {
return <BaseLayout authError={stringKeys.error.unauthorized}></BaseLayout>;
}
store.dispatch({ type: "ROUTE_CHANGED", url: computedMatch.url, path: computedMatch.path, params: computedMatch.params })
return <Component {...props} />;
}}
</ReactReduxContext.Consumer>;
}
} />
);
Ответ №1:
Вы отправляете действие в середине рендеринга, которое не является правильным. Вместо этого вам следует создать специальный компонент или компонент-оболочку для вашего входного компонента и отправить действие, как только компонент будет смонтирован
С оболочкой компонента класса:
class CompWithDispatch extends React.Component {
componentDidMount() {
const { store, type, url, path, params } = this.props;
store.dispatch({ type, url, path, params })
}
render() {
const { store, type, url, path, params , component: Component, ...rest} = this.props;
return <Component {...rest} />
}
}
С оболочкой функционального компонента
const CompWithDispatch = (props) => {
const { store, type, url, path, params, component:Component, ...rest } = props;
useEffect(() => {
store.dispatch({ type, url, path, params })
}, []);
return <Component {...rest} />
}
и используйте его, как
export const AuthRoute = ({ component, roles, computedMatch, ignoreRedirection, ...rest }) => (
<Route exact {...rest} render={props => {
return <ReactReduxContext.Consumer>
{({ store }) => {
const user = store.getState().appData.user;
if (!user) {
auth.setRedirectUrl(window.location.pathname);
return <Redirect to={auth.loginUrl} />;
}
const redirectUrl = auth.getRedirectUrl();
if (redirectUrl amp;amp; !ignoreRedirection) {
auth.removeRedirectUrl();
return <Redirect to={redirectUrl} />;
}
if (roles amp;amp; roles.length amp;amp; !roles.some(neededRole => user.roles.some(userRole => userRole === neededRole))) {
return <BaseLayout authError={stringKeys.error.unauthorized}></BaseLayout>;
}
const additionalProps = { type: "ROUTE_CHANGED", url: computedMatch.url, path: computedMatch.path, params: computedMatch.params })
return <CompWithDispatch {...additionalProps} {...props} component={component}/>;
}}
</ReactReduxContext.Consumer>;
}
} />
);