重新呈现URL响应中的相同组件

时间:2018-09-10 06:41:10

标签: javascript reactjs redux react-router react-props

我有一条路由,该路由带有一个id,并为每个id呈现相同的组件,例如:     <Route path='/:code' component={Card}/>

现在在Link标记中,我将一个ID传递给该组件。现在Card组件将根据传递的ID来获取其他详细信息。但是问题在于它仅针对一个ID呈现,并且如果我单击并转到下一个ID则不会更新。我搜索发现,可以使用componentsWillReceiveProps,但是在React的最新版本中,它已被弃用。那么该怎么做呢?

5 个答案:

答案 0 :(得分:13)

将当前位置作为组件上的键可以解决问题。

<Route path='/:code' component={(props) => <Card {...props} key={window.location.pathname}/>}/>

答案 1 :(得分:1)

我只是遇到了类似的问题。我认为您正在将更新/渲染和重新安装混为一谈。当我处理生命周期方法时,This图对我有所帮助。

如果您的问题像我的一样,则您的组件类似

class Card extend Component {
  componentDidMount() {
    // call fetch function which probably updates your redux store  
  }

  render () {
    return // JSX or child component with {...this.props} used, 
           // some of which are taken from the store through mapStateToProps
  }
}

第一次访问安装该组件的URL时,一切正常,然后,当您访问使用同一组件的另一条路线时,则没有任何变化。那是因为没有重新安装组件,而是因为某些道具改变了,至少this.props.match.params在改变而只是在更新。

但是在组件更新时不会调用componentDidMount()(请参见上面的链接)。因此,您将不会获取新数据并更新您的redux存储。您应该添加一个componentDidUpdate()函数。这样,您可以在道具更改时再次调用获取函数,而不仅仅是在最初安装组件时。

componentDidUpdate(prevProps) {
  if (this.match.params.id !== prevProps.match.params.id) {
    // call the fetch function again
  }
}

查看反应documentation,了解更多详细信息。

答案 2 :(得分:0)

执行以下操作:

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.match.params.id !== prevState.match.params.id) {
    // Here
  }
}

答案 3 :(得分:0)

在React Router v4中,在路由器解决问题后添加Switch标签

答案 4 :(得分:0)

我实际上想出了另一种方法。

我们将从您的示例代码开始:<Route path='/:code' component={Card}/>

您想要做的是让<Card>是一个包装器组件,最好具有功能(它实际上不需要我不认为的任何状态),并通过向下传递来呈现要呈现的组件{...props}来支持您的道具,以便获得路由器属性,但重要的是为其提供一个key道具,它将迫使它从头开始重新渲染

例如,我有一个看起来像这样的东西:

<Route exact={false} path="/:customerid/:courierid/:serviceid" component={Prices} />

我希望URL更改时重新呈现组件,但仅在customerid或serviceid更改时重新呈现。因此,我将Prices变成了这样的功能组件:

function Prices (props) {
    const matchParams = props.match.params;
    const k = `${matchParams.customerid}-${matchParams.serviceid}`;
    console.log('render key (functional):');
    console.log(k);
    return (
        <RealPrices {...props} key={k} />
    )
}

请注意,我的密钥仅考虑了customerid和serviceid-当这两个密钥更改时,它将重新呈现,但是当courierid更改时,它不会重新呈现(如果需要,可以将其添加到密钥中)。我的RealPrices组件的好处是仍然可以传递所有路线道具,例如历史记录,位置,比赛等。