Search code examples
reactjsreduxreact-reduxfetchredux-thunk

Getting an array from the redux store puts it inside another array


So what I am doing is the following:

An action fetches a .json file from a url and dispatches another action. The value for pilots is [Array(278)].

export const pilotsFetchDataSucces = (pilots) => {
  return {
    type: 'PILOTS_FETCH_DATA_SUCCES',
    pilots
  }
};

export const pilotsFetchData = (url) => (dispatch) => {
  fetch(url)
  .then((response) => {return response.json()})
  .then((pilots) => {
    dispatch(pilotsFetchDataSucces(pilots))
  })
  .catch((e) => {console.log('Error in pilotsFetchData', e)});
};

This is the reducer:

const pilotsReducer = (state = [], action) => {
  switch(action.type){
    case 'PILOTS_FETCH_DATA_SUCCES':
    console.log('pilotsReducer', action.pilots);
    return [
      ...state,
      action.pilots
    ];

    default:
    return state;
  }
}

export default pilotsReducer;

Later in my component I want to access this data. I'm using mapStateToProps.

import React from 'react';
import { connect } from 'react-redux';
import SinglePilot from './SinglePilot.js';
import { pilotsFetchData } from '../actions/pilots';

class Pilots extends React.Component {

  componentDidMount () {
 this.props.fetchData('https://raw.githubusercontent.com/guidokessels/xwing-data/master/data/pilots.js');
  }

  render(){
    return (
      <div>
        <h1>Title</h1>
        {this.props.query && <p>You searched for: {this.props.query}</p>}
        {
          //iterate over all objects in this.props.pilots
          this.props.pilots.map( (pilot) => {
            return (
            <SinglePilot
              key={pilot.id}
              name={pilot.name}
           />
          )})
        }
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
      pilots: state.pilots // is [[Array(278)]] instead of [Array(278)]
    });

const mapDispatchToProps = (dispatch) => ({
  fetchData: (url) => dispatch(pilotsFetchData(url))
});

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

The problem I have is that the value of state.pilots is now an array of length 1 and the array that I want (with a length of 278) is inside this array.

I know I could fix this by using state.pilots[0], but I don't like that. What is causing my initial pilots array to be wrapped inside another array?

Many thanks for any assistance!

Edit: added the code for the reducer.


Solution

  • As pilots is also an array, you need to spread it as well.

    Instead of

    return [
      ...state,
      action.pilots
    ]
    

    return your new state as

    return [
      ...state,
      ...action.pilots
    ]