Компонент изменения состояния без повторного рендеринга - PullRequest
0 голосов
/ 20 мая 2019

Я нигде не мог найти ответ, потому что у меня ничего не получалось, поэтому я начинаю новую тему.Пожалуйста, не отмечайте его как дубликат


Router.js:

<Switch>
   <Route path="/" exact component={Home} />
   <Route exact path="/p/:uid" component={Profile} />
</Switch>

Profile.js

constructor(props) {
  super(props);
  this.state = {
    loading: true,
    profile_user_id: this.props.match.params.uid,
  };
}

Затем, позже в Profile.js, я запускаю выборку для получения данных из бэкэнда и сохраняю эти данные в состояние, используя this.setState ({...}).Когда рендерится компонент Profile, все выглядит нормально.

В Router.js есть также ссылка:

<Link to={"/p/" + this.state.ntuser.tag}>Profile</Link>

.., которая должна перейти в ваш собственный профиль.Поэтому, когда ваш идентификатор пользователя равен 1, и вы посещаете профиль пользователя с идентификатором 22, ваш URL будет / p / user22, а ссылка будет указывать на /p/user1.

Проблема в том, что дажеНесмотря на то, что профили отображаются правильно, компонент Profile не становится повторно отображаемым, когда вы нажимаете на ссылку (которая должна направить вас в / p / user1 и показать ваш профиль вместо этого).Я также пытался сохранить местоположение из реакции-маршрутизатора в состояние, поэтому при каждом изменении URL-адреса он будет перехвачен в componentWillReceiveProps () и внутри я обновляю состояние.Но все равно ничего.Есть идеи?

PS: я использую React.Component

Ответы [ 3 ]

1 голос
/ 20 мая 2019

console.log(this.props.match.params.uid) в constructor, componentDidMount() и componentDidUpdate() (UNSAFE_componentWillReceiveProps() устарело)

Число и места (из вызовов журнала) сообщат вам, если компонент воссоздан (много вызовов конструктора)) или обновленный (вызовы cDM).Переместите ваш вызов извлечения данных соответствующим образом (в cDM или cDU ... или sCU).

Вы можете сохранить общие данные в компоненте выше <Router/> (например, используя контекстный API) - но это не требуется вв этом случае.


Решение

Вы можете обновить состояние из измененных реквизитов , используя componentDidUpdate () или shouldComponentUpdate () .componentDidUpdate должен быть защищен условиями, предотвращающими бесконечный цикл.См. документы .

Простейшее решение:

componentDidUpdate(prevProps) {
    if (this.props.some_var !== prevProps.some_var) {
        // prop (f.e. route '.props.match.params.uid') changed
        // setState() - f.e. for 'loading' conditional rendering
        // call api - use setState to save fetched data
        // and clearing 'loading' flag 
    }
}

shouldComponentUpdate() можно использовать для некоторых оптимизаций - минимизировать повторные визуализации.

0 голосов
/ 20 мая 2019

Вот что происходит:

  1. Вы идете в /p/user22.
  2. React рендерит <Route exact path="/p/:uid" component={Profile} />.
  3. Маршрут визуализирует компонент Profile в первый раз.
  4. Компонент Profile вызывает конструктор, в то время как this.props.match.params.uid равно "user22". Следовательно, this.state.profile_user_id теперь "user22".
  5. Вы нажимаете на ссылку на /p/user1.
  6. React рендерит <Route exact path="/p/:uid" component={Profile} />, то есть тот же маршрут .
  7. Маршрут затем воспроизводит тот же компонент профиля , но с различными реквизитами .
  8. Так как это один и тот же компонент Profile, не обновляет состояние .

Это объясняет, почему вы все еще видите профиль пользователя22

0 голосов
/ 20 мая 2019

У меня была такая же проблема в моем проекте, я не нашел ни одной хорошей работоспособной идеи, кроме как подумать:

import {Profile} from "../Profile "

<Link to={`your href`}
            onClick={userChanged}/>

..........

function userChanged() {
  const userCard= new Profile();
  userCard.getProfileData();
}

Прежде всего, вам нужно сделать компонент профиля как export class Profile extends React.Component (экспорт без значения по умолчанию).

getProfileData - это метод, в котором я получаю данные из моего API и помещаю их в состояние. Это перезапустит ваше приложение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...