Как повторно отобразить компоненты реакции при изменении URL-адреса?

У меня такой маршрут:

<BrowserRouter>
      <Switch>
        <Route path="/question/:title" component={Item} />
      </Switch>
    </BrowserRouter>

Компонент использует axios для извлечения данных и обновления контента на сайте, это делается в функции componentWillMount:

componentWillMount(){
        const {title} = this.props.match.params;
        axios.get(server + '/api/question/slug/' + title)
                .then(response => {
                    this.setState({
                        question: response.data,
                        loading: false
                    })

                })
    }

Проблема в том, что, допустим, я нахожусь на странице site.com/question/this-is-an-article и использую <Link to="/question/second-article">Second Article</Link> для навигации, это похоже на то, что функция componentWillMount не вызывается, поэтому прежний контент все еще остается на странице. Как я могу заставить функцию componentWillMount запускаться при изменении URL-адреса?


person Nengak dakup    schedule 21.12.2019    source источник
comment
возможный дубликат stackoverflow.com/questions/38915066/ и stackoverflow.com/questions/52252353/   -  person Andy    schedule 03.11.2020


Ответы (3)


Прежде всего, предпочтительнее использовать безопасный жизненный цикл response-lifecycle-methods-diagram < / а>

Поскольку вы используете react-router-dom, вы можете получить свой URL через такие реквизиты рендеринга, см. Документ здесь

history.location.pathname

Так что вы можете попробовать проверить, изменился ли url в shouldComponentUpdate вот так

shouldComponentUpdate(prevProps, prevState) {
  return this.props.history.location.pathname !== prevProps.history.location.pathname
}

Вы можете добавить в него дополнительные условия или просто предотвратить сложные условия с помощью настройки конструкции компонентов.

person keikai    schedule 21.12.2019
comment
shouldComponentUpdate не должен быть goto для этого; В случае вопроса, когда title изменяется - компонент получает новые реквизиты для обновленного заголовка - только он не реагирует на эти обновленные реквизиты. Такие методы, как _3 _ / _ 4_ (если вы используете более старую версию, в противном случае используйте UNSAFE точно) / _ 5_ лучше подходят для обновления состояния на основе свойств. - person H S; 21.12.2019
comment
@HS Это причина, по которой эти жизненные циклы не являются предпочтительными, поскольку не рекомендуется обновлять состояние на основе реквизитов, о чем вы можете обратиться к этому Контроль качества - person keikai; 21.12.2019
comment
то что вы собираетесь делать с проверкой того, изменился ли URL-адрес с помощью shouldComponentUpdate в вашем ответе - не измените ли вы состояние смонтированного компонента с помощью более нового ответа, вызванного более новой «опорой». - person H S; 21.12.2019

Попробуйте использовать componentDidUpdate для вызова axios. Обязательно - вы хотите вызывать api при изменении параметра title (a prop).

Вы также можете попробовать _2 _ / _ 3_.

P.S. - используйте componentDidMount вместе с вышеупомянутым правильно. Найдите здесь жизненный цикл http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

person H S    schedule 21.12.2019
comment
запускается ли componentDidUpdate при первом / первоначальном рендеринге? - person Nengak dakup; 21.12.2019
comment
@Nengakdakup, вы можете узнать больше о жизненных циклах здесь - projects.wojtekmaj.pl/react -схема-методы-жизненный цикл; - person H S; 21.12.2019
comment
@Nengakdakup - в отношении ответа он указывает на озабоченность по поводу того, что аксиомы вызываются в результате обновленных свойств. - person H S; 21.12.2019

Я думаю, вам не нужен жизненный цикл (если да, просто используйте componentDidMount):

class App extends Component {
  constructor() {
    super();
    this._initHistoryListen();
  }
  _unListen = () => {};
  _initHistoryListen() {
    this._unListen = history.listen((location, action) => {
      const {
        title
      } = this.props.match.params;
      axios.get(server + '/api/question/slug/' + title)
        .then(response => {
          this.setState({
            question: response.data,
            loading: false
          })

        })
    });
  }
  componentWillUnmount(){
     this._unListen()
  }
}

person Alvin    schedule 21.12.2019