[英]React Re-renders When Parent State is Changed Through Child Component
在App.js中,我將setURL(page){ ... }
作為對HealthForm的支持。 在HealthForm中,我有一個輸入字段,該字段接受URL的String和一個按鈕,該按鈕發起對后端服務器的提取調用,並且一些數據會在promise對象中接收回來。 我也叫that.props.changeUrl(that.state.someURL);
在promiseStatus函數內部,因為那是我唯一可以放置它而不收到以下警告的地方:
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
但是,每次調用that.props.changeUrl(that.state.someURL)
,頁面都會重新渲染。 基本上-輸入字段和由於fetch調用而呈現的其他功能-全部重置。 但是App.js中的url狀態會更新。
為什么在調用父項道具時整個頁面都重新渲染?
如果僅刪除了那行that.props.changeUrl(that.state.someURL)
但該應用程序不會重新呈現,但是它當然不會更改該應用程序的狀態
我需要頁面不重新呈現,因為重要信息是在fetch調用之后呈現的,由於重新呈現會重置該路由,因此無法看到。
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
url: '',
};
this.setURL = this.setURL.bind(this);
}
setURL(link) {
this.setState({
url: link
});
}
render(){
return(
<MuiThemeProvider>
<Router>
<div className="App">
<Route path="/" component={Header}></Route>
<Route path="/health" component={()=>(
<HealthForm changeUrl={this.setURL}/>)}></Route>
<Route path="/path1" component={wForm}></Route>
<Route path="/path2" component={xForm}></Route>
<Route path="/path3" component={yForm}></Route>
<Route path="/path4" component={zForm}></Route>
</div>
</Router>
</MuiThemeProvider>
);
}
}
HealthForm.js
class HealthForm extends React.Component {
constructor(props) {
super(props);
this.state = {
exampleURL: '',
exampleURLError: '',
status: '',
showStatus: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
validate = () => {
//…checks for input errors
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
const err = this.validate();
let that = this;
if (!err) {
this.setState({
exampleURLError: ''
});
console.log(this.state);
var data = this.state.exampleURL
fetch('htpp://...', {
method: 'POST',
body: JSON.stringify(data)
})
.then((result) => {
var promiseStatus = result.text();
promiseStatus.then(function (value) {
that.setState({
status: value,
showStatus: true
});
that.props.changeUrl(that.state.jarvisURL);
});
}).catch((error) => {
console.log(error);
});
}
}
render() {
return (
<form>
<TextField
...
/>
<br/>
<Button variant="contained" size="small" color="primary" onClick={e => this.handleSubmit(e)} >
Check
</Button>
<br /> <br />
...
</form>
);
}
}
export default HealthForm;
之所以發生這種情況,是因為您在App
組件上調用setState()
,導致其重新呈現,包括重新創建您設置的所有路由。 我不確定您使用的是哪個路由器,但是似乎它是在路由下重新創建組件,可能是通過再次調用作為道具傳入的component
函數並獲取HealthForm
組件的新實例。
我假設App
中的所有組件都要求您將狀態存儲在App
中,這就是為什么要將其放置在其中? 如果不是,請將其向下移到HealthForm
組件中,但是如果是這樣,可能是時候考慮將狀態外部存儲到組件中了,例如,在諸如Redux之類的狀態容器中或其他具有Flux風格的東西中。
編輯:我認為您的問題的根源在這里:
<Route path="/health" component={()=>(<HealthForm changeUrl={this.setURL}/>)}></Route>
事實上,函數是作為component
prop傳遞的,每次都會導致component
的新實例。 我可以看到為什么需要這樣做,以將對setURL()
的引用傳遞到HealthForm
-通過從組件中提取狀態也可以避免這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.