redux React组件在存储状态更改时未更新

eeq64g8w  于 2023-05-18  发布在  React
关注(0)|答案(6)|浏览(283)

下面是我的组件类。该组件似乎从未执行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)

下面是map reducer:

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
  }
}

经过更多的测试和日志记录,当它将stateMap到props时,它用来Map到props的state对象包含正确的数据,因此state.map.data是正确的,我可以看到fetch的返回。然而,当我在componentWillUpdate()中记录这个.props时,数据对象在那里,但为空。

gkn4icbw

gkn4icbw1#

我也遇到过类似的问题,读了这篇文章后,我找到了答案:
通过reducer中处理操作的结果,在存储中设置/更新/删除数据。Reducer接收应用程序切片的当前状态,并期望获得新的状态。组件可能无法重新渲染的最常见原因之一是,您正在修改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}
对于阵列:[...theArray]
我希望这对你有帮助

db2dz4w8

db2dz4w82#

因为你没有改变引用,所以React的浅层比较不会检测到更新。
我将使用一个简单的例子与博客文章。在reducer中,您可能正在执行以下操作:

case FETCH_NEW_POSTS
    let posts = state.posts;
    posts.push(action.payload.posts);
    return {
        ...state, 
        posts
    };

相反,您必须执行以下操作:

case FETCH_NEW_POSTS
    let posts = [...state.posts]; // we're destructuring `state.posts` inside of array, essentially assigning the elements to a new array.
    posts.push(action.payload.posts);
    return {
        ...state, 
        posts
    };

根据您的用例,Object.assign()或lodash的clone/deepclone可能更符合您的习惯。

fkaflof6

fkaflof63#

componentWillUpdate接收传入的props * 作为参数 *。此时,this.props仍然是老 prop 。试着像这样改变你的方法:

void componentWillUpdate(nextProps, nextState) {
    L.geoJson(nextProps.data).addTo(this.map);
}
9rbhqvlz

9rbhqvlz4#

如果您通过maps文件将props传递给组件,请确保您正在监听maps文件中的存储。

export const listenToStores = [CommonStore, store];
@connection(maps.listenToStores, maps.getStateFromStores)
nwnhqdif

nwnhqdif5#

根据玛丽娜的回答

var tempArray = imageArrayState
tempArray.push(5)
setImageArray(tempArray)

var tempArray = []
imageArrayState.foreach(value => {tempArray.push(value)})
tempArray.push(5)
setImageArray(tempArray)

使我的应用程序刷新

gtlvzcf8

gtlvzcf86#

在我的情况下,我有同样的问题中提到的问题,我已经解决了它使用新的数组创建使用扩展运算符,而不是使用数组推送方法。

错误:rows.push(row)

const onAddRow = useCallback(rowIndex => {
        const rows = props.managefunds
        const row = rows.find((row, index) => {
            return rowIndex === index
        })
        rows.push(row) // while directly push in to array, page is not refreshing
        props.handleSubAccount({label: 'subAccount', value: rows })
    }, [ props.managefunds ])

解决方案:[ ...rows, row ]

const onAddRow = useCallback(rowIndex => {
        const rows = props.managefunds
        const row = rows.find((row, index) => {
            return rowIndex === index
        })
        props.handleSubAccount({label: 'subAccount', value: [ ...rows, row ]}) // while create new array in the following way, the page is refreshing properly
    }, [ props.managefunds ])

相关问题