URL change without re rendering in React router

梦想的初衷 提交于 2021-02-07 03:09:06

问题


I am working on an application where I need to change the url of the page without causing a re-render.

I am making a call to fetch all the pages inside componentDidMount like this

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

Once I have all the pages then I want to show the individual pages. For eg. in the url it has to be like /page/1/slug-for-page-1 and /page/2/slug-for-page-2 based on a state variable activePageNumber and the active page content will be displayed. Also the corresponding slug should be there on the url.

I tried adding a callback after setState like below, but it didn't work.

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

I thought of adding a child component to manage the activePageNumber state, but I am not sure if its the best way to do it and whether it'll prevent the re-render.

I can implement it such that each page make a separate request to the backend, but I wish to call it only once, and then update the url based on the active page number.

I am not sure how to implement this in react.

I have the following versions

"react-router-dom": "^5.0.0"

"react": "^16.8.6"


回答1:


If you define your /page route like this:

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

The Pages component method componentDidMount will be called when you switch from, for example, /home to /page/1, but will not be called when you switch from /page/1 to /page/2, because the DOM elements inside the /page/:number Route remain of the same type. I suggest you read React's documentation on reconciliation for a better explaination.

So you can safely put the call to your /pages service inside of the Pages component, and then in its render method display the page you need based on the activePageNumber prop.

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>
    );
  }
}


来源:https://stackoverflow.com/questions/56053810/url-change-without-re-rendering-in-react-router

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!