以下是我的组件类。该组件似乎永远不会执行componentWillUpdate(),即使我可以通过在mapStateToProps中返回之前的日志记录来查看状态更新。状态是100%更改,但组件不刷新。
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { search } from './mapActions'
import L from 'leaflet'
class Map extends Component {
componentDidMount() {
L.Icon.Default.imagePath = './images'
this.map = new L.Map('map', {
center: new L.LatLng(this.props.lat, this.props.lng),
zoom: this.props.zoom,
layers: L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '<a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
})
})
}
componentWillUpdate() {
console.log('UPDATE MAP')
L.geoJson(this.props.data).addTo(this.map)
}
render() {
return <div id="map"></div>
}
}
const mapStateToProps = (state) => {
return {
isFetching: state.isFetching,
data: state.data
}
}
const mapDispatchToProps = (dispatch) => {
return {
search: (name) => {
dispatch(search(name))
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Map)
这是地图缩减器:
const initialState = {
isFetching: false,
data: {}
}
export const map = (state = initialState, action) => {
switch(action.type) {
case 'REQUEST_SEARCH_RESULTS':
return Object.assign({}, state, {
isFetching: true
})
case 'RECEIVE_SEARCH_RESULTS':
return Object.assign({}, state, {
isFetching: false,
data: action.data
})
default:
return state
}
}
经过一些更多的测试和记录之后,似乎当它将状态映射到props时,它用于映射到props的状态对象包含正确的数据,因此state.map.data是正确的,我可以看到从取。但是当我在componentWillUpdate()中记录this.props时,数据对象就在那里但是空了。
答案 0 :(得分:8)
componentWillUpdate接收传入的道具作为参数。此时,this.props
仍旧是旧道具。尝试改变你的方法:
void componentWillUpdate(nextProps, nextState) {
L.geoJson(nextProps.data).addTo(this.map);
}
答案 1 :(得分:6)
我遇到了类似的问题,我在阅读完之后找到了答案:
通过处理Reducer中的操作的结果,在商店中设置/更新/删除数据。 Reducers接收应用程序片段的当前状态,并期望获得新的状态。组件可能无法重新呈现的最常见原因之一是您正在修改reducer中的现有状态,而不是返回具有必要更改的新状态副本(请查看“故障排除”部分)。当您直接改变现有状态时,Redux不会检测到状态差异,也不会通知组件存储已更改。 因此,我一定要检查你的减速机,并确保你没有改变现有状态。希望有所帮助! (https://github.com/reactjs/redux/issues/585)
当我尝试使用Object.assign({}, object)
时,它无论如何都没有用。我发现这个时就是这样:
Object.assign只生成浅拷贝。 (https://scotch.io/bar-talk/copying-objects-in-javascript)
然后我明白我必须这样做:JSON.parse(JSON.stringify(object))
或者只是这样:
{...object}
我希望这会对你有所帮助
答案 2 :(得分:1)
我遇到了与玛丽娜类似的问题,我以类似的方式解决了这个问题。希望这种解释对某人有帮助。
我将在博客文章中使用一个简单的示例。在减速器中,您可能正在执行以下操作:
ggplot(faithful, aes(x = eruptions, y = waiting)) + stat_density_2d(aes(fill = stat(level)), geom = "polygon", bins = 4)
相反,您必须执行以下操作:
case FETCH_NEW_POSTS
let posts = state.posts;
posts.push(action.payload.posts);
return {
...state,
posts
};
在第一个示例中,奇怪的是,您正在设置实际状态对象。这意味着您所做的任何更改都不会被接受,因为它们没有通过setState等效方法运行。
答案 3 :(得分:0)
此外,在使用组件的构造函数时要小心。那是我的问题。
例如
class extends Component {
private elementState: ElementState // BAD idea!!
constructor(props: any) {
super(props)
elementState = stateFromReduxStore // BAD idea!!!
}
render() {
return <SomeElement state={elementState} /> // will not be updated!!!
}
}
答案 4 :(得分:0)
如果要通过地图文件将道具传递给组件,请确保您正在听地图文件中的商店。
export const listenToStores = [CommonStore, store];
@connection(maps.listenToStores, maps.getStateFromStores)