我迷失了方向。也许你可以帮我。我试图检测道具何时已更改已安装组件的componentDidUpdate内部。过去效果不错。我什至有一个工作正常的测试(下面的代码中的refreshData)。 SOMEHOW是否可以通过componentDidUpdate(prevProps)检测到的方式传递道具?
在component.js中:
componentDidUpdate(prevProps){
//works fine
if ( this.props.refreshData !== prevProps.refreshData ) {
if ( this.props.refreshData )
this.refreshData();
}
//these two arent calling
if ( this.props.selectedCountries !== prevProps.selectedCountries ) {
if ( this.props.selectedCountries )
console.log('updated selected countries');
}
if ( this.props.selectedLocations !== prevProps.selectedLocations ) {
console.log('updated selected locations');
}
}
并在App.js中传递以下道具:
selectLocation = (id, type, lng, lat, polydata, name, clear = false) => {
//console.log(type);
//console.log(lng);
//console.log(lat);
//console.log(polydata);
let selectedType = 'selected' + type;
let previousState = [];
if (clear) {
this.setState({
selectedCountries: [],
selectedLocations: [],
selectedServices: [],
selectedPoints: [],
mapCenter: [lng, lat],
locationGeoCoords: [polydata]
})
previousState.push(id);
} else {
previousState = this.state[selectedType];
if (previousState.indexOf(id) === -1) {
//push id
previousState.push(id);
} else {
//remove id
var index = previousState.indexOf(id)
previousState.splice(index, 1);
}
}
if (type === "Countries") {
this.setState({
selectedCountries: previousState,
refreshData: true,
})
} else if (type === "Locations") {
this.setState({
selectedLocations: previousState,
refreshData: true
})
} else if (type === "Points") {
this.setState({
selectedPoints: previousState,
refreshData: true
})
}
}
render() {
return (
<component
selectedCountries={this.state.selectedCountries}
selectedLocations={this.state.selectedLocations}
refreshData={this.state.refreshData} />
}
}
答案 0 :(得分:2)
嗨:),正如我的评论中所述,问题出在您的App.js文件中-您正在对数组进行变异。换句话说,当您想创建一个新的选定国家/地区数组以传递时,实际上是在更新原始数组,因此当您进行比较时,总是会比较两个完全相同的数组。
尝试像这样更新您的App.js-
selectLocation = (id, type, lng, lat, polydata, name, clear = false) => {
//console.log(type);
//console.log(lng);
//console.log(lat);
//console.log(polydata);
let selectedType = 'selected' + type;
let previousState = [];
if (clear) {
this.setState({
selectedCountries: [],
selectedLocations: [],
selectedServices: [],
selectedPoints: [],
mapCenter: [lng, lat],
locationGeoCoords: [polydata]
})
previousState.push(id);
} else {
previousState = [].concat(this.state[selectedType]);
if (previousState.indexOf(id) === -1) {
//push id
previousState.push(id);
} else {
//remove id
var index = previousState.indexOf(id)
previousState.splice(index, 1);
}
}
if (type === "Countries") {
this.setState({
selectedCountries: previousState,
refreshData: true,
})
} else if (type === "Locations") {
this.setState({
selectedLocations: previousState,
refreshData: true
})
} else if (type === "Points") {
this.setState({
selectedPoints: previousState,
refreshData: true
})
}
}
render() {
return (
<component
selectedCountries={this.state.selectedCountries}
selectedLocations={this.state.selectedLocations}
refreshData={this.state.refreshData} />
}
}
唯一的区别是您设置previousState
的行-我将其更新为
previousState = [].concat(this.state[selectedType]);
通过添加[].concat
,我每次都会有效地创建一个NEW数组,因此,当您通过push
/ splice
对数组应用更改时,您将只修改NEW数组。然后,将比较作为道具传递下来后,比较就可以正常工作了:)
出于您的阅读兴趣,我发现了一篇有关此内容的文章:https://medium.com/pro-react/a-brief-talk-about-immutability-and-react-s-helpers-70919ab8ae7c
答案 1 :(得分:1)
selectedCountries
和selectedLocations
是数组对象。它的参考永远不会改变。而是检查长度。
componentDidUpdate(prevProps){
if ( this.props.refreshData !== prevProps.refreshData ) {
if ( this.props.refreshData )
this.refreshData();
}
if ( this.props.selectedCountries.length > prevProps.selectedCountries.length ) {
if ( this.props.selectedCountries )
console.log('updated selected countries');
}
if ( this.props.selectedLocations.length > prevProps.selectedLocations.length ) {
console.log('updated selected locations');
}
}
在上面的代码段中,您似乎正在直接更改this.state
。国家应该是一成不变的。始终确保您concat
添加元素,filter
删除元素,因为它们创建了一个新数组,而不是使状态中的原始数组发生变化。我会在这些行中做些事情。
另外,最好将组件名称大写。
selectLocation = (id, type, lng, lat, polydata, name, clear = false) => {
//console.log(type);
//console.log(lng);
//console.log(lat);
//console.log(polydata);
let selectedType = "selected" + type;
let previousState = [];
let updatedData = [];
if (clear) {
this.setState({
selectedCountries: [],
selectedLocations: [],
selectedServices: [],
selectedPoints: [],
mapCenter: [lng, lat],
locationGeoCoords: [polydata]
});
} else {
const data = this.state[selectedType];
if (data.indexOf(id) === -1) {
//push id
updatedData = [...data, id];
} else {
updatedData = data.filter((value) => value !== id);
}
}
if(type) {
this.setState({
[selectedType]: updatedData,
refreshData: true
});
}
};
render() {
return (
<component
selectedCountries={this.state.selectedCountries}
selectedLocations={this.state.selectedLocations}
refreshData={this.state.refreshData}
/>
);
}
}
答案 2 :(得分:0)
您确定地点和国家/地区的道具确实在改变吗?如果是,则以下代码应该起作用:
componentDidUpdate(prevProps) {
if (this.props.selectedCountries.length !== prevProps.selectedCountries.length) {
console.log("updated selected countries");
}
if (this.props.selectedLocations.length !== prevProps.selectedLocations.length) {
console.log("updated selected locations");
}
}
我创建了一个小提琴以在此处展示效果: https://codesandbox.io/s/o580n8lnv5