Wahyu Setiawan
Wahyu Setiawan

Reputation: 99

React Redux Handling form cannot read property of undefined

i am learning redux here. I got problems when i submit my input. I have 2 text input and i want to store it in an array, but when i got the error. it seems like the app adding a new one undefined data, so i can't load the property of undefined. But when i used one params in actions, It works, i don't know why. It is first time i am using redux, i hope you can help me, thank you

actions.js

import { ADD_PERSON, DEL_PERSON} from '../constants';

export const addPerson = (person, age) => {
    return {
        type: ADD_PERSON,
        person,
        age
    }
}

export const delPerson = (person, age) => {
    return {
        type: DEL_PERSON,
        person,
        age
    }
}

my reducers

import { ADD_PERSON, DEL_PERSON} from '../constants';

const initState = {people: [{ name: 'Wahyu', age: '18' }]}

export default function peopleReducer(state = initState, action){
    switch (action.type) {
        case ADD_PERSON:
        return {
            people: [ 
            ...state.people,
            action.person,
            action.age,
            ],
        };
        case DEL_PERSON:
        return {
            people: state.people.filter(p => p.name !== action.person.name),
        };
        default:
        return state;
    }
}

components file

  state = {
    name: '',
    age: '',
  }
  addPerson = () => {
    if (this.state.name === '') return;
    this.props.dispatchAddPerson({
      name: this.state.name,
      age: this.state.age,
    });
  }
  deletePerson = (person) => {
    this.props.dispatchdeletePerson(person)
  }

render() {
  console.log(this.props.people)
    return (
      <View>
        <Text style={styles.title}>People</Text>
        <TextInput
          onChangeText={(name) => this.setState({name})}
          style={styles.input}
          value={this.state.name}
          placeholder="Name"
        />
        <TextInput
          onChangeText={(age) => this.setState({age})}
          style={styles.input}
          value={this.state.age}
          placeholder="Age"
        />
        <TouchableHighlight
          underlayColor="#ffa012"
          style={styles.button}
          onPress={this.addPerson}
        >
          <Text style={styles.buttonText}>Add Person</Text>
        </TouchableHighlight>
        {
          this.props.people.map((person, index) => (
            <View key={index} style={styles.person}>
              <Text>Name: {person.name}</Text>
              <Text>Age: {person.age} </Text>
              <Text onPress={() => this.deletePerson(person)}>Delete Person</Text>
            </View>
          ))
        }
      </View>
    )
  }
}

function mapStateToProps(state) {
    return{
      people: state.people.people
    }
  }
function mapDispatchToProps (dispatch) {
    return {
      dispatchAddPerson: (person,age) => dispatch(addPerson(person,age)),
      dispatchdeletePerson: (person) => dispatch(delPerson(person))
    }
  }

export default connect(
  mapStateToProps,
  mapDispatchToProps  
)(App)

this is the logger

here my error in emulator

Upvotes: 2

Views: 100

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

This line is incorrect in your reducer

case ADD_PERSON
        return {
            people: [ 
            ...state.people,
            action.person,
            action.age, <---this is wrong
            ],
        };

shouldhave been

case ADD_PERSON
        return {
            people: [ 
            ...state.people,
            action.person

            ],
        };

The action could be like:

export const addPerson = (person, age) => {
    return {
        type: ADD_PERSON,
        Object.assign({}, person , {age}),
    }
}

Upvotes: 2

Related Questions