0
votes

I am developing an application with react-native and redux. I want to save my favorite movies in the store. Thus I set up my actions, reducers, store, Provider, connect...

When I dispatch an action, the reducer is called and the state changes (I check with (nextState === state) however mapStateToProps is never called.

For information, the dispatch action and mapStateToProps come from the same component. This component is in a StackNavigator. Even though I only use the component, the problem remains the same.

I guessed that I was changing the state, but it is not the case I think. I have been stuck with this problem for a while, I checked all existing problems, none of the solutions solve mine.

The dispatcher:

 _toggleFavorite() {
    const action = { type: "TOGGLE_FAVORITE", value: this.state.film }
    this.props.dispatch(action)
  }

The reducer:

const initialState = { favoritesFilm: [] }
function toggleFavorite(state = initialState, action) {
  let nextState
  switch (action.type) {
    case 'TOGGLE_FAVORITE':
      const favoriteFilmIndex = state.favoritesFilm.findIndex(item => item.id === action.value.id)
      if (favoriteFilmIndex !== -1) {
        nextState = {
          ...state,
          favoritesFilm: state.favoritesFilm.filter( (item, index) => index !== favoriteFilmIndex)
        }
      }
      else {
        nextState = {
          ...state,
          favoritesFilm: [...state.favoritesFilm, action.value]
        }
      }
      console.log('state: ', state)
      console.log('nextState: ', nextState)
      console.log(nextState === state)
      return nextState
  default:
    return state
  }
}
export default toggleFavorite

The connection to the store:

const mapStateToProps = (state) => {
  console.log('changed')
  return {
    favoritesFilm: state.favoritesFilm
  }
}

export default connect(mapStateToProps)(FilmDetail)

The navigator:

const SearchStackNavigator = createStackNavigator({
      SearchBar: { 
        screen: SearchBar,
        navigationOptions: {
          title: 'Rechercher'
        }
      },
      FilmDetail: {
        screen: FilmDetail
      }
    })
export default createAppContainer(SearchStackNavigator)

App.js :

import Navigation from './src/Navigation/Navigation';
import store from './src/Store/configureStore'
import { Provider } from 'react-redux'

export default class App extends Component<Props> {
  render() {
    return (
      <Provider store={store}>
        <Navigation/>
      </Provider>
    );
  }
}

The log from reducers works. Here an example:

state:  – {favoritesFilm: []} 
nextstate:  – {favoritesFilm: Array} 
false

The log ('changed') never appears nor componentDidUpdate(). In addition, nothing is re-rendered.

Thank you in advance.

2

2 Answers

0
votes

As I understand that you didn't see console.log('changed') in mapStateToProps after dispatch action. Actually mapStateToProps just run once, after dispatch change in to reducer it will send new props to component so you can track by hook

static getDerivedStateFromProps(props, state)

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

example:

static getDerivedStateFromProps(props, state) {
  console.log('change', props);
}

For tracking Redux changes when develop I recommend use Redux devtool https://github.com/zalmoxisus/redux-devtools-extension This tool will save many time for you.

0
votes

Solution found....... After days of looking around ..... Problem of versions: Have react-native 0.57.4 and had react-redux 6.0.1 I changed react-redux to 5.1.0.