简体   繁体   中英

Reducers state update not calling render function of parent component . React/Redux

I have 3 components in which I have one function declared in parent and sending it to child to get callback and child component is sending that method to it's child.

That function is getting called on change of dropdown selection , and updating state from reducer. but after updating state , render function is not getting called.

1 ] Parent method

     onChangeTrackList(id, key) {
    if(id) {
        this.selectKey = key
        console.log(id+'comp'+key)
        this.props.fetchLiveRaceVideo(id, key)
    }
}

And passing this to below child 

<LiveVideoPanel  key = {key}  onChangeTrackList = {this.onChangeTrackList.bind(this)}/>

2 ] child component - Child is calling this method in other method and passing that method as a props to other child.

     _onChangeTrackList(key, trackId) {
    if(trackId) {
        this.props.onChangeTrackList(trackId, key)
    }
}

<ReactSelect onChange = {this._onChangeTrackList.bind(this, this.props.videoCount)} />

Now this is properly functioning and updating state in reducer. But my parent component's render function is not getting called even after updating state in reducer.

Below is my container code which is dispatching this action

import { connect } from 'react-redux'
import Wagers from 'pages/wagers'
import { getWagers } from 'actions/wagers'
import {getAccountBalance} from 'actions/authentication'
import { fetchLiveRaceVideo, toggleVideosx} from 'actions/liveTrackVideo'

  const mapStateToProps = (state) => {
    return {
        liveRaceVideos: state.liveTrackVideo.liveRaceVideos
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
    fetchLiveRaceVideo: (track, index) =>  {     dispatch(fetchLiveRaceVideo(track, index)) },
    toggleVideosx: () => { dispatch(toggleVideosx())}
}
}

const wagers = connect(
    mapStateToProps,
    mapDispatchToProps)
(Wagers)

   export default wagers

Reducer -

 import actions from 'actions'

export const liveTrackVideo = (state = [] , action) => {
switch(action.type){
    case actions.GET_LIVE_RACE_VIDEO_FAILURE: {
        return {
            isFetchingLiveRaceVideos: false,
            fetchLiveRaceVideosErrors: action.error,
            liveRaceVideos: [action.liveRaceVideos]
        }
    }
   // Below is response  ( I am getting updated state from here)
    case actions.GET_LIVE_RACE_VIDEO_PANEL_SUCCESS:
    {
        state.liveRaceVideos[action.index] = Object.assign(action.liveRaceVideos, {'index': action.index})

        return Object.assign({}, state, {
            isFetchingLiveRaceVideos: false,
            fetchLiveRaceVideosErrors: null,
            liveRaceVideos: state.liveRaceVideos
        })
    }
    case actions.TOGGLE_VIDEO:
        {
            return Object.assign({}, state, {
                isFetchingLiveRaceVideos: false,
                fetchLiveRaceVideosErrors: null,
                liveRaceVideos: [...state.liveRaceVideos, {'error': 0 , 'link' : ''}]
            })
        }
    default :
        return state
}

}

It seems that are passing the function to update the store to your parent component, but you are not being subscribed to redux store updates.

It would look something like this:

connect(
  (state) => ({yourKey: state...}),
  (dispatch) => ({fetchLiveRaceVideo: (id, key) => dispatch(...)})
)(LiveVideoPanel)

Also, the state you pass to your reducers is supposed to be immutable. Try to update the liveRaceVideos keys to something like this:

const newLiveRaceVideo = Object.assign(action.liveRaceVideos, {'index': action.index})

return Object.assign({}, state, {
    isFetchingLiveRaceVideos: false,
    fetchLiveRaceVideosErrors: null,
    liveRaceVideos: state.liveRaceVideos.slice(0, action.index).concat(newLiveRaceVideo, ...state.liveRaceVideos.slice(action.index + 1))
}

You are not changing the reference of liveRaceVideos variable.

Your case should be like this :

var liveRaceVideos = state.liveRaceVideos || [];
liveRaceVideos = [...liveRaceVideos];
liveRaceVideos[action.index] = Object.assign(action.liveRaceVideos, {'index': action.index});
 return Object.assign({}, state, {
            isFetchingLiveRaceVideos: false,
            fetchLiveRaceVideosErrors: null,
            liveRaceVideos: liveRaceVideos
        })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM