在 React 路由器中无需重新渲染即可更改 URL

IT技术 reactjs react-router
2021-05-16 18:27:50

我正在开发一个应用程序,我需要在不导致重新渲染的情况下更改页面的 url。

我正在调用以获取像这样的 componentDidMount 中的所有页面

componentDidMount() {    
    axios.get('/pages')
      .then(response => {
        this.setState({
          pages: response.data,
          slugs: response.data.pages.map(item => Slug(item.title))
        })
      })

拥有所有页面后,我想显示各个页面。例如。在url它必须像/page/1/slug-for-page-1/page/2/slug-for-page-2基于状态变量activePageNumber和活动页面的内容将被显示。相应的 slug 也应该在 url 上。

我尝试在 setState 之后添加一个回调,如下所示,但没有奏效。

() => this.props.history.push({
          pathName: '/page',
          state: {activePageNumber : activePageNumber},
        })

我想添加一个子组件来管理 activePageNumber 状态,但我不确定它是否是最好的方法以及它是否会阻止重新渲染。

我可以实现它,以便每个页面向后端发出单独的请求,但我希望只调用一次,然后根据活动页码更新 url。

我不确定如何在react中实现这一点。

我有以下版本

“react-router-dom”:“^ 5.0.0”

“react”:“^ 16.8.6”

1个回答

如果你这样定义你的/page路线:

<Route
  path="/page/:number"
  component={({ match }) => (
    <Pages activePageNumber={match.params.number} />
  )}
/>

Pages组件的方法componentDidMount当从,例如,切换将被调用/home/page/1,但将当从切换被调用/page/1/page/2,因为内部的DOM元素/page/:number路线保持相同类型的。我建议你阅读 React 的reconciliation文档以获得更好的解释。

因此,您可以安全地将/pages服务调用放在Pages组件内部,然后在其渲染方法中根据activePageNumberprop显示您需要的页面

class Pages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      pages: null,
    };
  }

  componentDidMount() {
    axios.get('/pages')
      .then(response => {
        this.setState({
          pages: response.data
        })
      });
  }

  render() {
    const { pages } = this.state;
    const { activePageNumber } = this.props;

    return pages ? (
      <Page page={pages[activePageNumber]} />
    ) : (
      <div>loading...</div>
    );
  }
}