Reputation: 425
Right now I am mapping over an array with an endpoint to my API. From there I am taking every link and calling a get request on each thing I map over. My issue is that I am not able to save everything into my redux state. I have tried using concat and push to take everything and put it all in one array in my redux state.
MomentContent.js:
componentDidMount () {
this.props.photos.map(photo => {
this.props.fetchPhoto(this.props.token, photo)}
)
}
index.js (actions):
export const fetchPhoto = (token, photo) => dispatch => {
console.log('right token')
console.log(token);
fetch(photo, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Token ${token}`,
}
})
.then(res => res.json())
.then(parsedRes => {
console.log('photo data')
console.log(parsedRes)
dispatch(getPhoto(parsedRes))
})
}
export const getPhoto = (photo) => {
console.log('RES')
console.log(photo)
return {
type: GET_PHOTO,
photo: photo
}
}
When I use concat (reducer):
import {
GET_PHOTO
} from '../actions';
const initialState = {
photo: []
}
const photoReducer = (state = initialState, action) => {
switch(action.type) {
case GET_PHOTO:
return {
...state,
photo: initialState.photo.concat([action.photo])
}
default:
return state;
}
}
export default photoReducer
When I use push (reducer):
import {
GET_PHOTO
} from '../actions';
const initialState = {
photo: []
}
const photoReducer = (state = initialState, action) => {
switch(action.type) {
case GET_PHOTO:
return {
...state,
photo: initialState.photo.push([action.photo])
}
default:
return state;
}
}
export default photoReducer
UPDATE (another issue):
I was able to get it to work with :
return {
...state,
photo: [...state.photo, action.photo]
}
The issue now is that every time I refresh the same data is pushed again, so everything multiplies. Is there a way to fix this?
Upvotes: 5
Views: 6921
Reputation: 3804
If action.photo
is an array, no need to wrap it with additional []
.
If you want the newly fetched photo array to combined with existing photo array in the Redux state, use state.photo.push
instead of initialState.photo.push
.
case GET_PHOTO:
return {
...state,
photo: state.photo.push(action.photo)
}
Upvotes: 1
Reputation: 22189
You need to merge your updatedState
and not initialState
to the reducer in order to update
Either using concat:
return {
...state,
photo: state.photo.concat([action.photo])
}
or using spread operator
return {
...state,
photo: [...state.photo, action.photo]
}
Upvotes: 5
Reputation: 281726
Javascript push method on array return you the new size of the array and hence it won't work correctly.
what you need is to use concat
or spread-syntax
case GET_PHOTO:
return {
...state,
photo: initialState.photo.concat([action.photo])
}
or
case GET_PHOTO:
return {
...state,
photo: [...initialState.photo, action.photo]
}
Upvotes: 0
Reputation: 680
the push does not work correctly in redux, the ideal is to use the spread operator to concatenate the arrays
return {
... state,
photo: [... initialState.photo, action.photo]
}
Upvotes: 3