使用Redirect时,React Parent Component完全重建

问题描述 投票:3回答:2

我正在尝试利用嵌套路由以维护屏幕上父组件的外观,并且当用户在选项卡结构中左右导航时,该选项卡式界面中的内容会更新。我不希望父组件重新安装甚至重新渲染,只有它的子组件才能更改。这是一个完全基于键盘的导航系统,因此我们不使用链接或单击事件,只需按键盘上的左/右/上/下/输入即可。

不幸的是,出于隐私原因,我无法分享我的确切代码,但这里是一般的代码结构(显然不可编译,只是为了获得我们的架构是什么样的)。

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

希望以上所有内容都有意义,它就像我认为我可以从我们疯狂的复杂应用程序中做到的那样简单。基本上:

  • 我们有一个应用程序,其路线使用唯一的ID,即。 myApp.com/category/1234
  • 在这个类别中,我们有一些导航到的选项卡,如蓝色,红色,黄色,并且对于每一个,我们希望将路径嵌套在上面并最终结束,例如myApp.com/category/1234/blue ,它只会更新屏幕的一部分

我遇到的问题是,无论我在哪里放置重定向,如果我使用精确或(非精确路径),或者如果我在重定向中使用push as true,则父组件始终重新安装。我最终得到了一个全新的父组件,它将清除在本地状态下保存的某些元素。应用程序永远不会重新安装,但父组件会重新安装。我只希望子组件重新安装,父母应该保持原样。最初,Category组件甚至是一个高阶组件,我们将其切换为一个普通组件类,但无论是否有条件地呈现特定情况,似乎也没有任何不同。

此外,I have been playing around with this codesandbox,并调整原始代码以更紧密地匹配我的项目,并利用链接和重定向,并且父应用程序组件似乎永远不会重新安装。所以...它看起来像是可能的,我只是不确定我做错了什么。

任何帮助将不胜感激:)谢谢!

javascript reactjs react-router react-router-dom nested-routes
2个回答
0
投票

这让我大吃一惊:https://github.com/ReactTraining/react-router/issues/6122

我意识到我们的App的Switch Routing使用的是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>
    );
  }
}

0
投票

我尝试使用渲染功能渲染路线和子路线,但看起来没有任何区别。

我已在以下位置创建了一个示例代码:https://codesandbox.io/s/mmp54j370j如果您在控制台中观察,那么每次我进入嵌套路由时,它仍会呈现所有父组件并更新它们。 (虽然不是再次启动构造函数)

如果没有“render”属性并只应用“component = {componentName}”,我可以实现同样的功能

看起来反应路由器只是在两种情况下都更新组件,而不是在调用嵌套路由时再次完全卸载和安装组件。

请让我知道如果我错过任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.