在 componentDidMount - react-router-dom v6 中导航
navigate in componentDidMount - react-router-dom v6
我第一次使用react-router-dom v6,我熟悉v4。
我有一个电影列表,每部电影都有一个 ID,如果用户在 url 中输入了错误的电影 ID,我需要导航到未找到的页面。
我正在使用 class 组件的问题,所以我坚持使用 componentDidMount 导致以下错误
You should call navigate() in a React.useEffect(), not when your component is first rendered.
这是我的代码:
componentDidMount() {
let { id } = this.props.params;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) return this.props.navigate('/not-found', { replace: true });
this.setState({ data: this.mapToViewModel(movie) });
}
如前所述,我正在使用 class 组件,因此我将 class 作为函数导出,以使 Useparams() 与我一起工作
function WithNavigate(props) {
let navigate = useNavigate();
return <MovieForm {...props} params={useParams()} navigate={navigate} />;
}
export default WithNavigate;
我现在的问题是如何使导航在 componentDidMount 中工作!
提前致谢
嗯,实际的解决方案是如何使用 useNavigate
,或者您可以制作 wrapperComponent
使其成为通用解决方案,您可以在代码库的任何地方使用它
import { useNavigate } from 'react-router-dom';
export const withNavigate = (Component) => {
const Wrapper = (props) => {
const navigate = useNavigate();
return (
<Component
navigate={navigate}
{...props}
/>
);
};
return Wrapper;
};
现在你只有一个包装函数,你所要做的就是将你的组件包装在你想使用的地方 useNavigate
并像这样使用它 this.props.navigate('/not-found')
import React from 'react';
import {withNavigate} from 'src/hooks/withNavigate';
class MovieForm extends React.Component{
// .... rest of the code
componentDidMount() {
let { id } = this.props.params;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) return this.props.navigate('/not-found');
this.setState({ data: this.mapToViewModel(movie) });
}
// .... rest of the code
}
export default withNavigate(MovieForm);
componentDidMount
在 useEffect()
之后渲染
对于简单的修复,您可以添加
let { navigate } = this.props;
像这样添加您的代码,setTimeOut
componentDidMount() {
let { id } = this.props.params;
let { navigate } = this.props;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) {
return setTimeOut(()=> this.props.navigate('/not-found', { replace: true }));
}
this.setState({ data: this.mapToViewModel(movie) });
}
您 defining/using WithNavigate
作为 React 包装器组件而不是作为高阶组件,这改变了 useNavigate
挂钩的使用方式和传递给 class组件。
而不是
function WithNavigate(props) {
let navigate = useNavigate();
return <MovieForm {...props} params={useParams()} navigate={navigate} />;
}
转换为 HOC
function withNavigate = Component => props => {
const navigate = useNavigate();
const params = useParams();
return <Component {...props} params={params} navigate={navigate} />;
}
export default withNavigate;
然后装饰MovieForm
组件为默认导出
export default withNavigate(MovieForm);
我第一次使用react-router-dom v6,我熟悉v4。
我有一个电影列表,每部电影都有一个 ID,如果用户在 url 中输入了错误的电影 ID,我需要导航到未找到的页面。
我正在使用 class 组件的问题,所以我坚持使用 componentDidMount 导致以下错误
You should call navigate() in a React.useEffect(), not when your component is first rendered.
这是我的代码:
componentDidMount() {
let { id } = this.props.params;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) return this.props.navigate('/not-found', { replace: true });
this.setState({ data: this.mapToViewModel(movie) });
}
如前所述,我正在使用 class 组件,因此我将 class 作为函数导出,以使 Useparams() 与我一起工作
function WithNavigate(props) {
let navigate = useNavigate();
return <MovieForm {...props} params={useParams()} navigate={navigate} />;
}
export default WithNavigate;
我现在的问题是如何使导航在 componentDidMount 中工作!
提前致谢
嗯,实际的解决方案是如何使用 useNavigate
,或者您可以制作 wrapperComponent
使其成为通用解决方案,您可以在代码库的任何地方使用它
import { useNavigate } from 'react-router-dom';
export const withNavigate = (Component) => {
const Wrapper = (props) => {
const navigate = useNavigate();
return (
<Component
navigate={navigate}
{...props}
/>
);
};
return Wrapper;
};
现在你只有一个包装函数,你所要做的就是将你的组件包装在你想使用的地方 useNavigate
并像这样使用它 this.props.navigate('/not-found')
import React from 'react';
import {withNavigate} from 'src/hooks/withNavigate';
class MovieForm extends React.Component{
// .... rest of the code
componentDidMount() {
let { id } = this.props.params;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) return this.props.navigate('/not-found');
this.setState({ data: this.mapToViewModel(movie) });
}
// .... rest of the code
}
export default withNavigate(MovieForm);
componentDidMount
在 useEffect()
对于简单的修复,您可以添加
let { navigate } = this.props;
像这样添加您的代码,setTimeOut
componentDidMount() {
let { id } = this.props.params;
let { navigate } = this.props;
const genres = getGenres();
this.setState({ genres });
const movieId = id;
if (movieId === 'new') return;
const movie = getMovie(movieId);
if (!movie) {
return setTimeOut(()=> this.props.navigate('/not-found', { replace: true }));
}
this.setState({ data: this.mapToViewModel(movie) });
}
您 defining/using WithNavigate
作为 React 包装器组件而不是作为高阶组件,这改变了 useNavigate
挂钩的使用方式和传递给 class组件。
而不是
function WithNavigate(props) {
let navigate = useNavigate();
return <MovieForm {...props} params={useParams()} navigate={navigate} />;
}
转换为 HOC
function withNavigate = Component => props => {
const navigate = useNavigate();
const params = useParams();
return <Component {...props} params={params} navigate={navigate} />;
}
export default withNavigate;
然后装饰MovieForm
组件为默认导出
export default withNavigate(MovieForm);