ReakyMark's avatar

React redux this.props.data.map is not function

i'm new to redux i had no idea how to fix it i follow other user topic to use redux. final result is this error

this is json from server

[
  {
    "id":7,
    "name":"Smart Phone",
    "count_product":25,
    "product":{
        "id":125,
        "name": " V5",
        "image":"v5_01-06-2018-1515204450.jpg",
        "price":"55.00"
    }
  },
  {etc.....}
]

this is my actions

export default function loadCategory() {
  const request = axios.get('http://domain.com/api/category');
  return {
    type: 'LOAD_CATEGORY',
    payload: request,
  };
}

this is my Reducer

export default function ProductReducer(state = {}, action) {
  const LOAD_CATEGORY = 'LOAD_CATEGORY';
  switch (action.type) {
    case LOAD_CATEGORY:
    
      const newState = Object.assign({}, ...state, action.payload.data)
            console.log(newState); //// result [object, object]
      return newState;
    default:
      return state;
  }
}

this is my index.js

componentWillMount() {
    this.props.loadCategory();
  }
  render() {

const state = this.props.data;
      
     if(state){
      state.map((item) => {
        console.log('newState: ' + item); //// state.map is not function if
    //// if i use  Object.keys(state).map((item) => {
       ////                    console.log('newState: ' + item); /////// it return 0 1 2 3
      ////                 });
      });
      
        return (
        <Text>Hello 
       !</Text>
      )
    } else {
      return (
        <Text>No movies listed</Text>
      );
    }
  }
}

function mapStateToProps(state) {
  return { data: state.data };
}

export default connect(mapStateToProps, { loadCategory })(Product);

Thank in advanced

0 likes
3 replies
ejdelmonico's avatar

First of all, when you create an action.js file, make sure you do not export default because it will eventually cause you problems. Just export const Something = () => {}.

Try

return state.map(item => {
  ...state,
  action.payload.data
})

or something like that to fit your code.

ReakyMark's avatar

@ejdelmonico above solution not work but after i remove {} from object assign it return value as i expected

const newState = Object.assign(...state, action.payload.data);

this result like json from my api
[{
    "id":7,
    "name":"Smart Phone",
    "count_product":25,
    "product":{
        "id":125,
        "name": " V5",
        "image":"v5_01-06-2018-1515204450.jpg",
        "price":"55.00"
    }
  },
  {etc.....}
]

if i add {} back

const newState = Object.assign({}, ...state, action.payload.data);

this result like this

{
 0:{
    "id":7,
    "name":"Smart Phone",
    "count_product":25,
    "product":{
        "id":125,
        "name": " V5",
        "image":"v5_01-06-2018-1515204450.jpg",
        "price":"55.00"
    }
  },
  {etc.....}
}

is this a right solution to remove {} from object assign or ... ?

and another solution is add action.payload.data as object bcoz my data from laravel has remove wrapper

const ProductReducer = (state = {data:[]}, action) => {....});

const newState = Object.assign({}, state, {data: action.payload.data});

  1. which is good way ?

  2. does i shouldn't use Resource::withoutWrapper(); ?

must let it wrap by data for best practice ?

{
  data: [
    {id: 1, .....}m
    etc......
  ]
}

so i don't need to make action.payload.data as {data: action.payload.data} ?

ejdelmonico's avatar

If you you look closely at the documentation about actions and reducers, you will notice a particular way to perform actions and also the use of connect(). The way I described above is the way in which actions are to be defined.

Please or to participate in this conversation.