componentDidUpdate 没有触发
Posted
技术标签:
【中文标题】componentDidUpdate 没有触发【英文标题】:componentDidUpdate is not firing 【发布时间】:2017-08-15 18:10:18 【问题描述】:当我使用 react-router 更改路由时是否会触发 componentDidUpdate?我修改了示例代码,但似乎无法正常工作。
我让 home 组件记录了一些文本,但它似乎没有触发。任何帮助表示赞赏,谢谢!
代码:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import
BrowserRouter as Router,
Route,
Link
from 'react-router-dom'
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component=Home/>
<Route path="/about" component=About/>
<Route path="/topics" component=Topics/>
</div>
</Router>
)
class Home extends React.Component
render()
return (<div>
<h2>Home</h2>
</div>);
componentDidUpdate()
console.log("Updated!");
const About = () => (
<div>
<h2>About</h2>
</div>
)
const Topics = ( match ) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to=`$match.url/rendering`>
Rendering with React
</Link>
</li>
<li>
<Link to=`$match.url/components`>
Components
</Link>
</li>
<li>
<Link to=`$match.url/props-v-state`>
Props v. State
</Link>
</li>
</ul>
<Route path=`$match.url/:topicId` component=Topic/>
<Route exact path=match.url render=() => (
<h3>Please select a topic.</h3>
)/>
</div>
)
const Topic = ( match ) => (
<div>
<h3>match.params.topicId</h3>
</div>
)
ReactDOM.render(
<BasicExample />,
document.getElementById('root')
);
【问题讨论】:
【参考方案1】:根据DOC:
更新可能是由 props 或 state 的更改引起的。这些方法 在重新渲染组件时调用:
componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
渲染()
componentDidUpdate()
componentWillUpdate:
componentWillUpdate() 在新渲染之前立即调用 正在接收道具或状态。以此为契机 在更新发生之前进行准备。不调用此方法 用于初始渲染。
在 Home 组件中,您没有定义任何 state
并且您也没有使用任何 props
,这就是为什么不会调用 function
的原因。
查看此示例 componentDidUpdate
将在您单击 Click Me 文本时被调用:
class Home extends React.Component
constructor()
super();
this.state = a: false
componentDidUpdate()
console.log("Updated!");
render()
return (
<div>
<h2>Home</h2>
<p onClick=()=>this.setState(a: !this.state.a)>Click Me</p>
</div>
);
ReactDOM.render(<Home/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
【讨论】:
请注意,componentWillUpdate()
和 componentWillReceiveProps()
现在是 deprecated
对我不起作用。我正在更新构造函数中的状态,但 react-router 仍然没有触发我的 componentDidUpdate【参考方案2】:
建议的小改动:不推荐将对象传递给 setState 方法。使用 prevState 属性并翻转它的值。
class Home extends React.Component
constructor()
super();
this.state = a: false
componentDidUpdate()
console.log("Updated!");
render()
return (
<div>
<h2>Home</h2>
<p onClick=()=>this.setState((prevState) => (a: !prevState.a))>Click Me</p>
</div>
);
ReactDOM.render(<Home/>, document.getElementById('app'))
【讨论】:
您能否提供有关“不推荐将对象传递给 setState 方法”的更多信息?我没听说过。 是的。而且我认为“已弃用”不是正确的词。我应该说一个“坏习惯”,我的理解是 React 早在 React 17 就将停止支持将对象传递给 setState 方法。作者在这里很好地涵盖了这个主题:[链接] (daveceddia.com/why-not-modify-react-state-directly)但本质上,状态是不可变的。当您将对象传递给 setState 时,您将直接修改当前状态。这么小的应用程序不会受到影响,但它可能会导致烦人且难以定位的错误。 P.S.,我更新了我推荐的更改,以正确地将调用 setState 隐式返回的对象包装在括号中。在这两个示例之间,您将一个对象传递给 setState ,它直接改变了它的值。我正在返回一个对象,该对象使用 prevState 参数作为缓冲区,根据其最近的状态更改状态的值。 我认为您可能误解了您链接到的文章。文章中的问题是:this.state.cart.push(item.id);问题不是这样的: this.setState(foo: !this.state.foo) 前者直接改变状态。后者使用所有不可变对象。 我找到了您所建议的参考。我不认为你上面的链接涵盖了它。您的链接是关于突变的。您建议反对的问题是在计算 this.setState 的输入时使用 this.state。本文建议不要这样做:itnext.io/react-setstate-usage-and-gotchas-ac10b4e03d60 它说:“由于 setState 的异步性质,不建议使用 this.state 来获取 setState 中的先前状态。相反,始终依赖 prevState 方式”以上是关于componentDidUpdate 没有触发的主要内容,如果未能解决你的问题,请参考以下文章
使用 componentDidUpdate 在反应中更新状态