我是新来的反应者,它的生命周期是这样,所以当前正在学习一些教程,我陷入了一个问题,即componentWillReceiveProps生命周期方法无法按我期望的方式工作。 事实是,在 App 组件中,我正在将prop isActive传递给 Card 组件,并且当输入复选框处于选中状态/未选中状态时,它正在更改其值,因此我希望componentWillReceiveProps生命周期要触发的方法。但是,这根本不起作用。在这种情况下,您有什么可以建议的?我也愿意寻求最佳实践建议。谢谢您的宝贵时间。
组件代码:
//App.js
import React, {Component} from 'react';
import Ticker from "./Ticker/Ticker";
import currencies from './currencies';
import Card from "./Card/Card";
import uuid from "uuid";
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
class App extends Component {
state = {
activePairs: []
};
handleCheckbox = (rateId, event) => {
const {checked} = event.target;
this.setState(({activePairs}) => {
let pairs = [...activePairs];
if (checked) {
if (!pairs.includes(rateId)) {
pairs.push(rateId);
}
} else {
let index = pairs.findIndex(rate => rate === rateId);
pairs.splice(index, 1);
}
return {
activePairs: pairs
};
});
};
render() {
return (
<div className="App">
<Ticker handleCheckbox={this.handleCheckbox.bind(this)}/>
<div className="container">
<div className="row">
{currencies.map(pair => <Card key={"card-" + uuid.v4()} currency={pair}
isActive={this.state.activePairs.includes(pair)}/>)}
</div>
</div>
</div>
);
}
}
export default App;
//Card.js
import React, {Component} from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import '../App.css';
class Card extends Component {
state = {
value: 0
};
componentWillReceiveProps(nextProp) {
console.log(nextProp);
if (!this.props.isActive && nextProp.isActive) {
this.updateExchangeRate();
this.interval = setInterval(this.updateExchangeRate, 3000);
} else if (this.props.isActive && !nextProp.isActive) {
clearInterval(this.interval);
this.setState({
value: 0
})
}
}
updateExchangeRate = () => {
return fetch(`https://www.cbr-xml-daily.ru/daily_json.js`).then(r => r.json()).then(res => {
let exRate = res["Valute"][this.props.currency.toUpperCase()]['Value'] + (Math.random() * (0.99 - 0.01 + 1) + 0.01);
let maximum = exRate + 5.00;
let minimum = exRate - 5.00;
this.setState({
value: (Math.floor(Math.random() * (maximum - minimum + 1)) + minimum).toFixed(2)
});
});
};
render() {
return (
<div className="col-md-3 col-sm-6 mb-3">
<div className="card text-center text-white bg-info">
<div className="card-header bg-info">{this.props.currency.toUpperCase() + " to RUB"}</div>
<div className="card-body">
<h5 className="card-title">Current exchange pair:</h5>
<p className="card-text">{this.state.value}</p>
</div>
</div>
</div>
);
}
}
export default Card;
//Ticker.js
import React, {Component} from 'react';
import currencies from "../currencies";
export default class Ticker extends Component {
state = {
currencies: currencies
};
render() {
return (
<div id="wrapper">
<div id="sidebar-wrapper">
<ul id="sidebar-ul" className="sidebar-nav">
{this.state.currencies.map(currency => {
return <li key={currency}>
<input id={currency + "-input"} type="checkbox" onChange=
{
this.props.handleCheckbox.bind(this, currency)
}/>
<label htmlFor={currency + "-input"} className="text-info"
role="button"> {currency.toUpperCase()} rate</label>
</li>
})}
</ul>
</div>
</div>
);
}
}
//currencies.js
export default ["aud", "azn", "gbp", "bgn", "usd", "eur"];
答案 0 :(得分:1)
好吧,我终于在这里找到了引起问题的原因。在App组件中,我将uuid模块用作每个Card组件的关键道具,因此,每次isActive道具进行更新时,它总是渲染一个新的Card组件。
解决方案:使用常量ID代替它作为关键道具。