Closed EasonWang01 closed 8 years ago
If you found the solution please share it in a comment so other people who find this issue know how you solved it. Thanks!
I was using below works good ,but still don't know why others give error when it return [object Object]
but still says must return an object
case 'TOGGLE_TODO':
return Object.assign({},state,{todos:state.todos.map(function(state){
if(state.id!==action.id){
return state
};
return {...state,completed:!state.completed}
}) }
)
Why are you posting the reducer code? The error says mapStateToProps
returned something that isn’t a plain object. Not the reducer.
My guess is your mapStateToProps
returns something like state.todos
which will not work. The point of that function is to provide props to component, so it has to return an object with those props. Rather than pass state.todos
you would probably want { todos: state.todos }
.
If this is the case, we need to make a better error message that detects arrays. Contributions are welcome.
The problem here is that the error message isn't clear enough, an object is being passed in but it isn't a plain object until EasonWang01 uses Object.assign()
. checkStateShape
calls _.isPlainObject
which requires Object.prototype == null
or to have been created with Object.constructor
. The error message could probably be updated to read %sToProps must return a plain object. Instead received %s
The wording for computeMergedProps
could be updated as well to reflect this.
the mapStateToProp is look like this
import React, { Component } from 'react'
import TodoInput from './TodoInput.js'
import TodoList from './TodoList.js'
import {connect} from 'react-redux'
class App extends Component {
render() {
return (
<div>
<h1>Todo list</h1>
<TodoInput />
<TodoList todos={this.props}/>
</div>
)
}
}
function mapStateToProp(state){
return state
}
export default connect(mapStateToProp)(App)
I guess it might be that I'm not using combineReducer so I need to return the full state to store,not sure~ (◕ᴥ◕) ʕ·ᴥ·ʔ
Can you provide a full project reproducing the problem on GitHub? These pieces don't quite add up in my mind. For example it is strange you are passing the whole props object as todos prop down.
Hi, https://github.com/EasonWang01/Redux-tutorial/tree/link it's the origin version.
in Redux folder=> reducer.js
change to below and click initial for demo
let getId = 1 ;
export default function reducer(state,action){
switch(action.type){
case 'ADD_TODO':
return( Object.assign({},state,{
todos:[{
text:action.text,
completed:false,
id:getId++
},...state.todos]
})
)
case 'TOGGLE_TODO':
return state.todos.map(function(state){
if(state.id!==action.id){
return state
};
return {...state,completed:true}
});
case 'SET_VISBILITY_FILTER':
return Object.assign({},state,{visbility:action.filter})
default:
return state;
}
}
then the error appear,I think it just some miss typed by me, not a big problem need to solve ( ´ ▽ ` )b
But one thing I found is when some error occur in reducer.js the console.error will always point to some component file rather than reducer.js file.
Normally you return an object like { todos: Array<Todo> }
:
case 'ADD_TODO':
return( Object.assign({},state,{
todos:[{
text:action.text,
completed:false,
id:getId++
},...state.todos]
})
)
However when handling TOGGLE_TODO
, you return just an Array<Todo>
:
case 'TOGGLE_TODO':
return state.todos.map(function(state){
if(state.id!==action.id){
return state
};
return {...state,completed:true}
});
This is missing Object.assign({}, state, { todos: ... })
.
Then this state
gets returned from mapState()
which is where the error fires. Fixing the reducer to return the object would fix the problem. I also suggest you to use reducer composition as Egghead series shows, rather than put all the code into a single big reducer.
Hope it helps!
thanks!
hi,I'm new to this
the error message is
browser.js:40 Uncaught Invariant Violation:
mapStateToPropsmust return an object. Instead received [object Object].
1.(from egghead ) this will throw the error,but I don't know why.
But if I not using
return
beforestate.todos.map
it is fine2.
if I change to this it will not change the store
3. only
and
can successfully update the store and no error message,but this will also change the prev state,
how can I change this code? Thanks for reply.