状态更改未重新呈现组件

时间:2019-05-20 10:53:49

标签: reactjs react-router

我在任何地方都找不到答案,因为没有任何帮助。因此,我开始了一个新话题。请不要将其标记为重复


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({...})将数据保存到状态。呈现“个人档案”组件后,一切看起来都很好。

在Router.js中,还有一个链接:

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

..应该转到您自己的个人资料。因此,当您的用户ID为1并访问ID为22的用户的个人资料时,您的URL将为/ p / user22,链接将指向/ p / user1。

问题是,即使概要文件呈现得很好,单击链接时,概要文件组件也不会重新呈现(这将把您定向到/ p / user1并显示您的概要文件)。我也尝试将位置从react-router保存到状态,因此每次URL更改时,它都会被componentWillReceiveProps()和更新状态所捕获。但是仍然没有。有什么想法吗?

PS:我正在使用React.Component

3 个答案:

答案 0 :(得分:1)

{{1}中的console.log(this.props.match.params.uid)constructor中的componentDidMount()(不推荐使用componentDidUpdate()

(日志调用的)数目和位置将告诉您是重新创建组件(许多construcor调用)还是更新组件(cDM调用)。相应地将数据提取调用(移至cDM或cDU ...或sCU)。

您可以将公用数据保存在UNSAFE_componentWillReceiveProps()上方的组件中(例如,使用上下文api)-但是在这种情况下,这不是必需的。


解决方案

您可以使用componentDidUpdate()或shouldComponentUpdate()从更改的道具更新状态。 <Router/>应该有防止无限循环的条件保护。参见docs

最简单的解决方案:

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 } } 可用于某些优化-最小化重新渲染。

答案 1 :(得分:0)

在我的项目中也遇到了同样的问题,没有发现任何可行的想法,只是想像这样:

import {Profile} from "../Profile "

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

..........

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

首先,您需要将Profile组件设置为export class Profile extends React.Component(无默认导出)。

getProfileData是从api获取数据并将其置于状态的方法。这将重新渲染您的应用

答案 2 :(得分:0)

发生了什么事

  1. 您转到/ p / user22。
  2. 反应渲染<Route exact path="/p/:uid" component={Profile} />
  3. 该路线首次呈现“轮廓”组件。
  4. Profile组件将调用构造函数,此时this.props.match.params.uid等于“ user22”。因此,this.state.profile_user_id现在是“ user22”。
  5. 您单击/ p / user1的链接。
  6. 反应性渲染<Route exact path="/p/:uid" component={Profile} />,它是同一条路线
  7. 然后路线呈现相同的配置文件组件,但使用不同的道具
  8. 由于它是相同的配置文件组件,因此它不会更新状态

这说明了为什么您仍然看到user22的个人资料