Salvo
Salvo

Reputation: 107

Dispatch function doesn't update initial state, React Redux

I'm learning Redux for React Native, and I'm trying to make an app in which you type name and lastname,and by pressing the button it starts the functions addItem which adds name, and lastname to the array list, and sumbitItem, which launches the dispatch function, the problem is that when I launch the dispatch, it doesn't update initial state array list, it just doesn't do anything.

export class List extends Component {
      constructor(props) {
        super(props);
    this.state = {
      list: this.props.list,
      name: '',
      lastname: '',
      
        };
  }


  addItem = ( name, lastname ) => {   
  let list = this.state.list
    const  item = {
        key: Math.random(),
        name: name,
        lastname: lastname,
      };
      list.push(item);
      this.props.updateList(list);
  };


  render(){
    return(
 
        <Button onPress={() => this.addItem()}>
         <Text>Press Submit</Text>
        </Button>

    )}

Reducers

const initialState = {
  currentUser: null,
  list: [],
};



    export const user = (state = initialState, action) => {
      switch (action.type){
          case USER_STATE_CHANGE:
            return {
              ...state,
              currentUser: action.currentUser,
            };
          case 'ADD_ITEM': 
          return{
            ...state,
            list: action.list,
          }
          default:
            return state
      }
      
    };

Upvotes: 0

Views: 311

Answers (2)

Rajdeep D
Rajdeep D

Reputation: 3900

There are a few improvements need to be done.

  1. You need to wrap your component in connect
  2. You need to create and Action.js

Component

import { connect } from 'react-redux'
import { updateList } from './action'

export class List extends Component {
      constructor(props) {
        super(props);
    this.state = {
      list: this.props.list,
      name: '',
      lastname: '',
      
        };
  }


  addItem = ( name, lastname ) => {   
  
    const  item = {
        key: Math.random(),
        name: name,
        lastname: lastname,
      };
      this.setState({ list: [...this.state.list, item]})
  };

  submitItem = ( list ) => {
    () => this.props.updateList(list);
     this.props.navigation.navigate('list');
  }

  render(){
    return(
 
        <Button onPress={() => {this.addItem(this.state.name, this.state.lastname); this.submitItem(this.state.list)}}>
         <Text>Press Submit</Text>
        </Button>

    )}

mapStateToProps = (state) => {
   return state
}

mapDispatchToProps = {
  updateList
}

export default connect(mapStateToProps, mapDispatchToProps)(List );

Action.js

export const updateList = (list) => {
  return { type:"UPDATE_LIST", payload:list}
}

Reducers

const initialState = {
  currentUser: null,
  list: [],
};



    export const user = (state = initialState, action) => {
      switch (action.type){
          case USER_STATE_CHANGE:
            return {
              ...state,
              currentUser: action.currentUser,
            };
          case 'UPDATE_LIST': 
          return{
            ...state,
            list: [...action.payload],
          }
          default:
            return state
      }
      
    };

You can check this codesandbox, I have added end-to-end working code here.

Upvotes: 2

Vlad L
Vlad L

Reputation: 1685

You need to figure out what you're going to use global state (redux) for vs what you're using local state (this.state...) for.

It looks like you would like to set the list from local state to global state in submit item (although you called the action ADD_ITEM). In this case you need to pass the list to the reducer:

  submitItem = ( list ) => {
    this.props.dispatch({type:'ADD_ITEM', payload: list});
     this.props.navigation.navigate('list');
  }

Then in your reducer:

          case 'ADD_ITEM': 
          return{
            ...state,
            list: action.payload,
          }

This of course still won't be visible from your component but it should put the list into global state. If you want to control the list from global state rather than component state then you need to refactor the code so that ADD_ITEM actually adds the item into redux list, rather than your local state (which is what your current implementation is doing).

Upvotes: 1

Related Questions