Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React + Redux connect (mapStateToProps)

I have recently begun to work with React, and I'm enjoying it a lot even though I'm constantly running into problems.


Component #1 where I make a GET-request by a click on a button and I display some data in a table.

Component #2 is a input field, where I want to enter some data, and display it below, should be simple right?


When I dispatch a action, and have finished my GET-request, state looks like this:

{
    isFetching: false,
    isPressed: true,
    items: [{item: 1}, {item: 2}, {item: 3}]
}

Then I want to navigate to my other component. Do I need to unsubscribe to state here? Because when I navigate to my other page, where my other component is, the state will remain.

If I dispatch a action on my component #2 the state looks like this:

[
   {id: 1, text: 'foo'},
   {id: 2, text: 'bar'}
]

In both components I am using mapStateToPros, even though I don't really understand how it works, and thats where and why I'm running into problems I believe.

function mapStateToProps(state) {
     return state;
}

It just returns the state as of now. And when I switch between components, i will get errors messages. If I dispatch a action on my component #2 and then try to navigate to my component #1 (GET-REQUEST) I will get the following:

prev state Object { isFetching=false,  isPressed=true,  items=[10]}
action Object { type="ADD_TODO",  id=0,  text="asd"}
next state [Object { id=0,  text="asd"}]

Navigates to other page

Error: `mapStateToProps` must return an object. Instead received [object Object].

How should mapStateToProps be used in my scenario?

Do I need to use componentWillUnmount? Do Unsubscribe to my store?

I feel like I could ask a hundred questions, but I won't. I'm constantly reading the documentation but I'm still trying to figure it out.

Any links, advice on thought process, and other useful things are much appriecated.

EDIT:

This is my reducer:

As Ricky suggested below, I need to make my array into a object.

 case ADD_TODO: 
        return [
            ...state,
            todo(undefined, action)
        ]


  const todo = (state = [], action) => {

       case ADD_TODO:
            return {
                id: action.id,
                text: action.text
            }
   }

But, the "spread operator" will not work if I return a object instead of a array. Is there another option then (...) ?

like image 281
Cheese Puffs Avatar asked Oct 18 '22 16:10

Cheese Puffs


1 Answers

This is an array:

[
  {id: 1, text: 'foo'},
  {id: 2, text: 'bar'}
]

Make it an object:

{ 
  myData: [
   {id: 1, text: 'foo'},
   {id: 2, text: 'bar'}
  ]
}

And don't "unsubscribe" from state. Redux stores all state in one object. Each component selectively declares what properties of state they need within a function (mapStateToProps) supplied to Redux connect().

Edit

In response the the question update - you are passing in an array for the default state. Use an object:

const todo = (state = {}, action) => {
  // initialize your default state properties

  switch (action.type) {
     case ADD_TODO:
        return {
            ...state
            id: action.id,
            text: action.text
        }
     default: 
        return state;
   }
}

You might want to initialize default state properties in your reducer. But all this stuff is in the docs/examples.

Oh, and if you're asking me for more advice, it's a courtesy to upvote :)

like image 83
Rick Jolly Avatar answered Oct 27 '22 11:10

Rick Jolly