[英]Does a change in a React components props cause a re-render?
我正在構建一個簡單的計時器作為 React 實踐。 現在我只專注於讓幾秒鍾工作。 當用戶在baseSeconds
輸入選擇時,計時器將在該秒停止。
如果您將數字硬編碼為道具而不是傳遞狀態,它就會起作用。 並且我知道基於我作為測試輸出的{this.props.baseSeconds}
組件中的道具正在發生變化。 但是當我把this.state.baseSeconds
作為道具時,計時器會繼續運行。
設置的父組件:
const baseMin = [];
for (var i=0; i <= 60; i++) {
baseMin.push(i);
}
const baseSec = [];
for (var i=0; i <= 60; i++) {
baseSec.push(i);
}
const displayMinutes = baseMin.map((minute) =>
<option value={minute}>{minute}</option>
)
const displaySeconds = baseSec.map((second) =>
<option value={second}>{second}</option>
)
class Settings extends React.Component {
constructor(props) {
super();
this.state = {
baseMinutes: 0,
baseSeconds: 0,
varMinutes: 0,
varSeconds: 0
};
this.updateBaseMin = this.updateBaseMin.bind(this);
this.updateBaseSec = this.updateBaseSec.bind(this);
this.updateVarMin = this.updateVarMin.bind(this);
this.updateVarSec = this.updateVarSec.bind(this);
this.renderTimer = this.renderTimer.bind(this);
}
updateBaseMin(event) {
this.setState({ baseMinutes: event.target.value });
}
updateBaseSec(event) {
this.setState({ baseSeconds: event.target.value });
}
updateVarMin(event) {
this.setState({ varMinutes: event.target.value });
}
updateVarSec(event) {
this.setState({ varSeconds: event.target.value });
}
renderTimer(e) {
e.preventDefault();
const { baseMinutes, baseSeconds, varMinutes, varSeconds } = this.state;
return(
<Timer baseMinutes={baseMinutes} baseSeconds={baseSeconds} varMinutes={varMinutes} varSeconds={varSeconds}/>
)
}
render() {
const varMin = [];
for (var i=0; i <= this.state.baseMinutes; i++) {
varMin.push(i);
}
const displayBaseMin = varMin.map((minute) =>
<option value={minute}>{minute}</option>
)
const varSec = [];
for (var i=0; i <= this.state.baseSeconds; i++) {
varSec.push(i);
}
const displayBaseSec = varSec.map((second) =>
<option value={second}>{second}</option>
)
const { baseMinutes, baseSeconds, varMinutes, varSeconds } = this.state;
return (
<Container>
Settings
<form onSubmit={this.renderTimer}>BaseTime
<select onChange={this.updateBaseMin}>
{displayMinutes}
</select>
:
<select onChange={this.updateBaseSec}>
{displaySeconds}
</select>
VarTime +-
<select onChange={this.updateVarMin}>
{displayBaseMin}
</select>
:
<select onChange={this.updateVarSec}>
{displayBaseSec}
</select>
<input type="submit" value="Submit" />
</form>
<p>{this.state.baseMinutes}, {this.state.baseSeconds}, {this.state.varMinutes}, {this.state.varSeconds}</p>
<div>{this.renderTimer}</div>
<Timer baseMinutes={baseMinutes} baseSeconds={this.state.baseSeconds} varMinutes={varMinutes} varSeconds={varSeconds}/>
</Container >
)
}
}
export default Settings
Timer 的子組件:
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {
minutes: 0,
seconds: 0,
baseSeconds: this.props.baseSeconds
}
this.go = this.go.bind(this);
this.stop = this.stop.bind(this);
this.reset = this.reset.bind(this);
}
go = () => {
this.timer = setInterval(() => {
if ((this.state.seconds) === (this.props.baseSeconds)) {
clearInterval(this.timer);
} else {
this.setState({ seconds: this.state.seconds + 1 })
console.log(this.state.baseSeconds)
}
}, 1000)
}
stop = () => {
clearInterval(this.timer);
}
reset = () => {
this.setState({ minutes: 0, seconds: 0 })
}
render() {
return (
<div>
<button onClick={this.go}>start</button>
<button onClick={this.stop}>stop</button>
<button onClick={this.reset}>reset</button>
<p>{this.props.baseMinutes}:{this.props.baseSeconds}</p>
<p>{this.state.minutes}:{this.state.seconds}</p>
</div>
)
}
}
export default Timer
是的,默認情況下,道具的更改會導致重新渲染。 但是在您的情況下,在子組件中,初始狀態( baseSeconds
)基於不推薦的道具( this.props.baseSeconds
)。 構造函數只運行一次(當組件安裝時),並且在此之后的 baseSeconds 道具上的任何更新都不會被檢測到。 您可以直接在渲染中使用道具,而無需使用本地狀態。 如果您必須使用 props 更新本地狀態,推薦的方法是使用 getDerivedStateFromProps 生命周期方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.