Reputation: 107
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
Reputation: 3900
There are a few improvements need to be done.
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
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