我写了几十个React
个文件,从不使用componentDidUpdate
方法。
是否有需要使用此方法的典型示例?
我想要一些真实的例子,而不是一个简单的演示。
感谢您的回答!
答案 0 :(得分:54)
一个简单的例子是一个应用程序,它从用户收集输入数据,然后使用Ajax将所述数据上传到数据库。这是一个简化的例子(没有运行它 - 可能有语法错误):
export default class Task extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
name: "",
age: "",
country: ""
};
}
componentDidUpdate() {
this._commitAutoSave();
}
_changeName = (e) => {
this.setState({name: e.target.value});
}
_changeAge = (e) => {
this.setState({age: e.target.value});
}
_changeCountry = (e) => {
this.setState({country: e.target.value});
}
_commitAutoSave = () => {
Ajax.postJSON('/someAPI/json/autosave', {
name: this.state.name,
age: this.state.age,
country: this.state.country
});
}
render() {
let {name, age, country} = this.state;
return (
<form>
<input type="text" value={name} onChange={this._changeName} />
<input type="text" value={age} onChange={this._changeAge} />
<input type="text" value={country} onChange={this._changeCountry} />
</form>
);
}
}
因此,只要组件发生state
更改,它就会自动保存数据。还有其他方法可以实现它。 {<1}}在需要发生操作 >>更新DOM并清空更新队列时特别有用。它可能对复杂的componentDidUpdate
和renders
或DOM更改最有用,或者当您需要某些内容作为绝对最后要执行的内容时。
上面的例子很简单,但可能证明了这一点。改进可以是限制自动保存可以执行的次数(例如,每10秒最多一次),因为现在它将在每次击键时运行。
我也在这个fiddle上做了一个演示来演示。
有关详细信息,请参阅official docs:
更新发生后立即调用
state
。初始渲染不会调用此方法。将此作为在更新组件时对DOM进行操作的机会。只要您将当前道具与之前的道具进行比较(例如,如果道具未更改,则可能不需要网络请求),这也是进行网络请求的好地方。
答案 1 :(得分:2)
有时候,您可能会在构造器或componentDidMount中的props中添加状态值,当props更改但组件已经挂载时,可能需要调用setState,因此componentDidMount将不会执行,构造函数也不会执行;在这种特殊情况下,由于道具已更改,因此可以使用componentDidUpdate,可以使用新道具在componentDidUpdate中调用setState。
答案 2 :(得分:2)
此生命周期方法在更新发生时立即被调用。 componentDidUpdate()方法最常见的用例是响应prop或状态更改来更新DOM。
您可以在此生命周期中调用setState(),但请记住,您需要将其包装在某种条件下,以检查状态或支持对先前状态的更改。 setState()的不正确使用可能导致无限循环。 看下面的示例,该示例显示了此生命周期方法的典型用法示例。
componentDidUpdate(prevProps) {
//Typical usage, don't forget to compare the props
if (this.props.userName !== prevProps.userName) {
this.fetchData(this.props.userName);
}
}
在上述示例中,请注意,我们正在将当前道具与先前的道具进行比较。这是为了检查道具是否从当前状态发生了变化。在这种情况下,如果道具没有更改,则无需进行API调用。
有关更多信息,请参阅 official docs:
答案 3 :(得分:1)
componentDidUpdate(prevProps){
if (this.state.authToken==null&&prevProps.authToken==null) {
AccountKit.getCurrentAccessToken()
.then(token => {
if (token) {
AccountKit.getCurrentAccount().then(account => {
this.setState({
authToken: token,
loggedAccount: account
});
});
} else {
console.log("No user account logged");
}
})
.catch(e => console.log("Failed to get current access token", e));
}
}
答案 4 :(得分:1)
当状态发生变化时,您需要调用副作用(例如对api的请求-获取,放置,发布,删除)。因此,您需要呼叫componentDidUpdate()
,因为已经呼叫了componentDidMount()
。
在componentDidUpdate()中调用副作用之后,您可以根据then((response) => this.setState({newValue: "here"}))
中的响应数据将状态设置为新值。
请确保您需要检查prevProps
或prevState
以避免无限循环,因为在将状态设置为新值时,componentDidUpdate()将再次调用。
有两个地方可以称为最佳实践的副作用-componentDidMount()和componentDidUpdate()
答案 5 :(得分:0)
我在高图中使用了/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
.
.
.
etc
}
。
以下是此组件的一个简单示例。
componentDidUpdate()