React Router仅在第二次点击后更新

时间:2017-09-21 07:42:20

标签: reactjs react-router react-router-v4 react-router-dom

所以,基本上我有多个嵌套路由,如/:platform/:account/products/:tab/:productId/summary。 一切正常,直到我的实际单一产品组件,但react-router在我的单个产品标签中停止正常工作。 我有一个产品视图,带有标签(路线),当点击一个项目时,弹出的是单个产品视图,其中还有3个标签。

我的产品的子路线正在更新,但仅限于下一个渲染周期。

  1. 我在摘要中点击价格:没有任何反应 (路线更改为/:platform/:account/products/:tab/:productId/prices
  2. 我点击摘要:渲染的组件更改为价格 (路线更改为/:platform/:account/products/:tab/:productId/summary
  3. 我点击翻译:渲染的组件更改为摘要 (路线更改为/:platform/:account/products/:tab/:productId/translations
  4. 我再次点击翻译:渲染的组件更改为翻译 (根本没有路线变化)
  5. 我已经和你斗争了4个多小时,我检查了我的树上是否有PureComponent,我到处都使用withRouter,我还检查了我的产品组件没有更新(也许我的主视图组件阻止了更新),但一切似乎都很好,新道具是正确的。 我也尝试在{ pure: false }中使用connect(),但没有任何帮助。 我也删除了这个localize HOC以防万一,但这并没有解决它。

    4.2.0

    示例代码

    以下是我的组件中的精简渲染方法:

    class ProductView extends Component {
      componentWillReceiveProps() {
        console.log("UPDATED PRODUCT TAB")
      }
    
      render() {
        const { match, history, translate, lang, loading, data } = this.props
        console.log(match)
        return (
          <Modal>
              <TabList>
            <TabItem>
              <NavLink
                activeClassName="active"
                to={{
                  pathname: `/${match.params.platform}/${match.params.account}/products/${match.params.tab}/${match.params.productId}/summary`,
                  search: location.search,
                }}
              >
                {translate("Summary")}
              </NavLink>
            </TabItem>
            <TabItem>
              <NavLink
                activeClassName="active"
                to={{
                  pathname: `/${match.params.platform}/${match.params.account}/products/${match.params.tab}/${match.params.productId}/prices`,
                  search: location.search,
                }}
              >
                {translate("Prices")}
              </NavLink>
            </TabItem>
            <TabItem>
              <NavLink
                activeClassName="active"
                to={{
                  pathname: `/${match.params.platform}/${match.params.account}/products/${match.params.tab}/${match.params.productId}/translations`,
                  search: location.search,
                }}
              >
                {translate("Translations")}
              </NavLink>
            </TabItem>
          </TabList>
              <Switch>
                <Route path="/:platform/:account/products/:tab/:id/summary" component={Summary} />
                <Route path="/:platform/:account/products/:tab/:id/prices" component={Prices} />
                <Route path="/:platform/:account/products/:tab/:id/translations" component={Translations} />
              </Switch>
          </Modal>
        )
      }
    }
    
    const mapStateToProps = state => (...)
    
    const mapDispatchToProps = dispatch => (...)
    
    export default withRouter(connect(
      mapStateToProps,
      mapDispatchToProps,
    )(localize("translate")(ProductView)))
    

    获取产品组件的路线如下: <Route exact path="/:platform/:account/products/:tab/:productId/:productTab" component={ProductView} /> 添加或删除:productTab没有任何区别。 在具有此产品路径的组件内部,我有其他NavLinks用于选项卡,并且路由器正常工作。

    奇怪的是,组件一直更新到我的产品路线,并使用正确的match道具,但这些子路线(包括NavLink)仅在再次点击后更新。

    screenshot from 2017-09-20 18-44-22

3 个答案:

答案 0 :(得分:1)

如果您使用嵌套的RouteNavLink(Route的包装器),则需要使用Switch(为方便起见)来包装所有模态内容(或至少使用Route / NavLink的部分。

const location = (this. - if you component is not a function)props.location;
<Switch location={location}>
  <NavLink ... />
  <Route ... />
</Switch>

这将确保更新位置。

react-modal不会干扰用户组件的更新。路由接收的location来自getChildContext(),它仅在响应组件生命周期后更新。通过在render()上给切换位置,上下文将是新的,它将被赋予子路由。它将按预期工作。

答案 1 :(得分:0)

React-redux在其connect函数中实现纯渲染。这可能会阻止您的更新

尽早尝试使用withRouter。它将阻止connect阻止来自路由器的更新。

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(localize("translate")(withRouter(ProductView)))

答案 2 :(得分:0)

所以,我设法追踪它(不知道为什么我之前3小时没试过......)并且发现它是由于反应模式。

还有其他人有同样的问题,这是门票: https://github.com/reactjs/react-modal/issues/499