React Parent Component полностью реконструируется при использовании Redirect - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь использовать вложенные маршруты, чтобы сохранить внешний вид родительского компонента на экране, и когда пользователь перемещается влево и вправо в структуре вкладок, содержимое этого интерфейса вкладок обновляется.Я не хочу, чтобы родительский компонент перемонтировался или даже перерисовывался, меняются только его дочерние компоненты.Это полностью основанная на клавиатуре навигационная система, поэтому мы не используем ссылки или события щелчка, а просто нажимаем влево / вправо / вверх / вниз / ввод на клавиатуре.

К сожалению, я не могу поделиться своим точным кодом дляиз соображений конфиденциальности, но вот общая структура кода (очевидно, не компилируемая, просто чтобы понять суть нашей архитектуры).

в App.js

class App extends Component {
  render() {
    return (
      <div className="App">
        <Switch>
          <Route
            path="/"
            exact
            match={ true }
            component={ () => <MainMenu/> }
          />
          <Route
            path="/category/:uniqueID"
            exact
            component={ () => <CategoryComponent childArray=[child1, child2, child3] /> }
          />
      />
        </Switch>
      </div>
    );
  }
}

в CategoryComponent.js

class CategoryComponent extends Component {
  render() {
    var childRoutes;
    this.props.childArray.forEach(child => {
      childRoutes.push(
        <Route
          key=child.id
          path={ `${this.props.match.path}/${child.path}` }
          component={ () => <ChildComponent/> }
        />
      );
    });

    return (
      <div className="CategoryComponent">
        ... // a bunch of UI stuff goes here, including the navigation for the child components
        <Switch>
          { childRoutes }
        </Switch>
      </div>
    );
  }
}

и, наконец, в ChildComponent.js

class ChildComponent extends Component {
  shouldComponentUpdate(nextProps) {
    // because this navigation is done exclusively by keyboard,
    // each child has a property of selected or not that it gets from its parent,
    // so only the currently selected one should actually be doing the redirect
    if (!this.props.isSelected && nextProps.isSelected) {
      this.redirect = true;
    }
  }
  render() {
    var redirect;
    if (this.redirect) {
      redirect = 
        <Redirect
          to={ `${this.props.match.path}/${this.props.thisChildPath}` }
        />;
    }

    return (
      <div className="ChildComponent">
        { redirect }
      </div>
    );
  }
}

Надеюсь, все вышеперечисленное имело смысл, это настолько просто, насколько я думаю, я могу сделать это из нашего безумного сложного приложения,В основном:

  • у нас есть приложение с маршрутом, который использует уникальный идентификатор, т.е.myApp.com/category/1234
  • внутри этой категории, у нас есть несколько вкладок для навигации, таких как синий, красный, желтый, и для каждой из них мы хотим вложить маршрут внутри вышеупомянутого и ветрас чем-то вроде myApp.com/category/1234/blue, который обновит только часть экрана

Проблема, с которой я сталкиваюсь, заключается в том, что, независимо от того, где я размещаюперенаправляет, если я использую точные или (не точные пути), или если я использую push как true в Redirect, родительский компонент ВСЕГДА перемонтируется.Я получаю совершенно новый родительский компонент, который уничтожит некоторые элементы, сохраненные в локальном состоянии.Приложение никогда не перемонтируется, но родительский компонент делает.Я только хочу, чтобы дочерние компоненты перемонтировались, родительский должен оставаться точно таким, как есть.Первоначально компонент Category был даже компонентом высшего порядка, и мы переключили его только на один нормальный класс компонентов, но с условным рендерингом или без него, похоже, тоже ничего не изменилось.

Кроме того, Я поэкспериментировал с этими кодами и окном и адаптировал исходный код, чтобы он более точно соответствовал моему проекту и использовал и ссылки, и перенаправления, и родительский компонент приложения никогда не перемонтировался.Итак ... это кажется, что это возможно, я просто не уверен, что делаю не так.

Любая помощь будет принята с благодарностью :) спасибо!

Ответы [ 2 ]

0 голосов
/ 06 апреля 2019

Я пытался рендерить маршруты и суб-маршруты с помощью функции рендеринга, но похоже, что это не имеет никакого значения.

Я создал пример кода по адресу: https://codesandbox.io/s/mmp54j370j Если вы наблюдаете в консоли, то каждый разЯ иду по вложенному маршруту, он по-прежнему визуализирует все родительские компоненты и обновляет их.(хотя и не инициировал конструктор снова)

То же самое я мог бы достичь без свойства "render" и просто применяя "component = {componentName}"

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

Пожалуйста, дайте мне знать, если я что-то там пропускаю.

0 голосов
/ 27 ноября 2018

Это мне очень помогло: https://github.com/ReactTraining/react-router/issues/6122

Я понял, что в маршрутизации коммутатора нашего приложения используется component, что каждый раз вызывало реконструкцию.Переключив все на render, проблема была решена: D

Итак, App.js стал таким:

class App extends Component {
  render() {
    return (
      <div className="App">
        <Switch>
          <Route
           path="/"
            exact
            match={ true }
            render={ () => <MainMenu/> }
          />
          <Route
            path="/category/:uniqueID"
            exact
            render={ () => <CategoryComponent childArray=[child1, child2, child3] /> }
          />
      />
        </Switch>
      </div>
    );
  }
}
...