Marco Disco
Marco Disco

Reputation: 565

Redux does not update Array

moving from React Context to Redux probably I missed something I just want to update an array with the ADD_FAV type action

databaseReducer.js

import FOOD from "../../data/db/food";
import { ADD_FAV, FETCH_FOOD, SET_LOADING } from "../actions/DatabaseActions";

const initialState = {
  food: FOOD,
  favorites: [],
  loading: false,
};

export default (state = initialState, action) => {
  switch (action.type) {
    case ADD_FAV:
      return {
        ...state,
        favorites: [...state.favorites, action.payload],
        loading: false,
      };

databaseActions.js

export const ADD_FAV = "ADD_FAV";
export const FETCH_FOOD = "FETCH_FOOD";
export const SET_LOADING = "SET_LOADING";

export const addFav = (id) => {
  console.log("fav", id);  /// shows me that works
  return { type: ADD_FAV, payload: id };
};

then I call the action like this:

<TouchableOpacity onPress={() => addFavBtn(id)}>
<MaterialIcons name="favorite-border" size={25} />
</TouchableOpacity>

and I see the call in the console

FavoriteScreen.js

const FavoritesScreen = () => {
  // const { state, fecthFavorites, putInArray } = useContext(DatabaseContext);

  const favorites = useSelector((state) => state.database.favorites);

console.log(favorites)

but I always get an empty array, so means that it doesn't update it With REACT UseContext it worked. Any idea? thanks!

Upvotes: 1

Views: 52

Answers (2)

segFault
segFault

Reputation: 4054

Another approach to this would be to call dispatch from within the action creator and return that Promise.

databaseActions.js

export const ADD_FAV = "ADD_FAV";
export const FETCH_FOOD = "FETCH_FOOD";
export const SET_LOADING = "SET_LOADING";

export const addFav = (id) => {
  console.log("fav", id);  /// shows me that works
  return dispatch({ type: ADD_FAV, payload: id });
};

Example Component

import React from 'react';
import { connect } from 'react-redux';
import { addFav } from './databaseActions.js';

const ExampleComponent = ({ id, addFav }) => (
    <button onPress={() => addFav(id)}>
        Add Favorite
    </button>
);

export default connect({ /*mapStateToProps*/ }, { addFav })(ExampleComponent);

Personally, I like this approach as it doesn't require you to include the dispatch everywhere that you are calling your action. And allows you to make calls post-state update using a .then() if needed.

Upvotes: 0

Phoenix1355
Phoenix1355

Reputation: 1652

The issue is with the way to dispatch your action (As mentioned in the comments). First of all, you need to make sure that the component which dispatches the action has been bound to the redux store with the connect method from react-redux like so:

import React from 'react';
import { connect } from 'react-redux';

const ClickableComponent = ({ dispatch }) => {

    // The code that defines the id variable...

    return (
        <TouchableOpacity onPress={() => dispatch(addFavBtn(id))}>
            <MaterialIcons name="favorite-border" size={25} />
        </TouchableOpacity>
    );
};

export const connect()(ClickableComponent);

This way, the action gets dispatched to the store and the favorites list should update as expected. To verify this, you can use the browser debugger or use a console.log inside the reducer, to make sure you get the correct id with the action.

Upvotes: 1

Related Questions