React error saying Objects are not valid as react child - reactjs

I am getting the [Error: Objects are not valid as a React child (found: object with keys {counter, num}). If you meant to render a collection of children, use an array instead.] error for the below code :
const initialState = {
counter: 0,
num : 0
}
const counterReducer = (state = initialState, action) => {
switch(action.type){
case "INCREMENT":
{
return {
...state,
counter: state.counter + action.payLoad
}
}
case "DECREMENT":
return {
...state,
counter: state.counter - action.payLoad
}
default:
{
return state;
}
}
}
export default counterReducer;
If I do like below everything working fine:
const counterReducer = (state = 0, action) => {
switch(action.type){
case "INCREMENT":
return state + action.payLoad;
case "DECREMENT":
return state - action.payLoad;
default:
{
return state;
}
}
}
export default counterReducer;

You probably try to render somewhere the counter? Your default case returns the entire object, instead of just state.counter.
Try it like this:
const counterReducer = (state = initialState, action) => {
switch(action.type){
case "INCREMENT":
{
return {
...state,
counter: state.counter + action.payLoad
}
}
case "DECREMENT":
return {
...state,
counter: state.counter - action.payLoad
}
default:
{
return state.counter;
}
}
}
Or in the component where you render it access the object property state.counter

There's nothing wrong with the reducer you've written.
Without the corresponding component code and based on the error you're seeing, it seems that you're using the entire state object ({ counter: 0, num: 0 }, for example) within the React component that's using the state from this reducer.
Replacing the object ({ counter: 0, num: 0 }, from the above example) with just the counter value (obj.counter) should get it working

Related

Two Boolean states in the Init State of Reducer, One returns undefined

I've been working with redux for the last couple weeks and was incorporating it into my projects when I ran into this wall. Pretty common reducer for modals being rendered so i can animate them before unmounting them.
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
switch (action.type) {
case "modalInteraction":
return {
isModalOpen: action.payload
};
case "testModalInteraction":
return {
test: action.payload
};
default:
return state;
};
}
Sadly, the test property is still returning as undefined despite the fact that the other initial state in the same reducer can be called without a problem. I even removed all the testModalInteraction dispatches in the case that that somehow upset the datatype. I just can't spot the difference that keeps returning undefined.
When you return the new state, make sure to spread the initial state (...state) and then change whatever values you need to change.
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
switch (action.type) {
case "modalInteraction":
return {
...state,
isModalOpen: action.payload
};
case "testModalInteraction":
return {
...state,
test: action.payload
};
default:
return state;
};
}
If it is still undefined, make sure the payloads are defined for both actions.
For example, your modalInteraction action could look like
export const modalInteraction = (bool) => ({
type: "modalInteraction",
payload: bool
})
P.S., you can destructure the action object. This allows you to use "type" instead of "action.type" and "payload" instead of "action.payload".
const initialState = {
isModalOpen: false,
test: false
}
export default function(state = initialState, action) {
const {type, payload} = action;
switch (type) {
case "modalInteraction":
return {
...state,
isModalOpen: payload
};
case "testModalInteraction":
return {
...state,
test: payload
};
default:
return state;
};
}

Cannot read property 'todos' of undefined ReactJs,Redux

I just started to get familiar with Redux and I'm stuck on this error.I'm getting error Cannot read property 'todos' of undefined,On code below which is in component. :
const mapStateToProps = (item) => {
return {
todos: item.todos,
numberPerPage: item.numberPerPage,
currentPage: item.currentPage
};
};
This is my Storage :
const initialState = {
todos: [],
numberPerPage: 10,
currentPage: 1
}
const reducer = (state =initialState, action) => {
const { items, numberPerPage, currentPage } = state;
switch (action.type) {
case actionTypes.ADD_ITEM:
return {
...state,
todos: [
...items,
{
value: action.value,
checked: action.checked,
_id: action.id,
},
],
currentPage: Math.ceil((items.length + 1) / numberPerPage)
};
case actionTypes.GET_ALL:
return {
...state,
todos: action.items,
};
}
}
export default reducer;
Any Suggestions?
You do not have a default case in your reducer which is what causes the error.
When the reducer is initially set up, redux dispatches an ##redux/INIT action at which point of time your reducer returns undefined resulting in an error when you try to access the state value
Adding a default case to return state will overcome this issue and solve your problem
const reducer = (state =initialState, action) => {
const { items, numberPerPage, currentPage } = state;
switch (action.type) {
case actionTypes.ADD_ITEM:
return {
...state,
todos: [
...items,
{
value: action.value,
checked: action.checked,
_id: action.id,
},
],
currentPage: Math.ceil((items.length + 1) / numberPerPage)
};
case actionTypes.GET_ALL:
return {
...state,
todos: action.items,
};
default: return state;
}
}

React JS, logical error in Redux state updation

My Todo code accepts new todo from users and update the Redux store. There seems to be a problem with my reducer function
const initialState = {
tasks: ['notodo'],
completedTasks: ['nothing']
}
const todoState = (state = initialState, action) => {
switch(action.type) {
case 'ADDTODO':
return {
...state,
tasks: [...tasks, action.payload]
};
default:
return state;
}
}
case 'ADDTODO':
return {
...state,
tasks: [...tasks, action.payload] // Here ...tasks is undefined
};
It should be [...state.tasks, action.payload]

Why is the state in mapStateToProps undefined?

reducers/counter.js
export type counterStateType = {
+ctr: number,
+counter: boolean
};
type actionType = {
+type: string,
+value: any
};
export default function counter(state: counterStateType = { ctr: 0, counter: true}, action: actionType) {
console.log("Reducer called with");
console.log(state);//has valid value ie { ctr: 0, counter: true}
switch (action.type) {
case TOGGLE:
state.counter = !state.counter;
return state;
case UPDATE:
state.ctr = action.value;
return state;
default:
return state;
}
}
counterPage.js
function mapStateToProps(state) {
console.log("mapStateToProps called with");
console.log(state.counter);
return {
ctr: state.counter.ctr,//<= undefined
counter: state.counter.counter
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(CounterActions, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
PS: The above is on router LOCATION_CHANGE
The issue was in reducer, I had forgotten about immutablity of redux states. modifying,
switch (action.type) {
case TOGGLE:
state.counter = !state.counter;
return state;
case UPDATE:
state.ctr = action.value;
return state;
default:
return state;
}
to
switch (action.type) {
case TOGGLE:
return {ctr: state.ctr, counter: !state.counter};
case UPDATE:
return {ctr: action.value, counter: state.counter};
default:
return state;
}
solved it.

Adding and Removing Data from/to State in Redux/React using Lodash

I have a table with check boxes. When a user selects a check box, the id is sent to an action creator.
Component.js
handlePersonSelect({ id }, event) {
const { selectPerson, deselectPerson } = this.props;
event.target.checked ? selectPerson(id) : deselectPerson(id);
}
action.js
export function selectPerson(id) {
console.log("selected")
return {
type: SELECT_PERSON,
payload: id
};
}
export function deselectPerson(id) {
return {
type: DESELECT_PERSON,
payload: id
};
}
I'm able to go all the way up to this step, at which I'm lost:
This is the offending code:
import {
SELECT_PERSON,
DESELECT_PERSON,
FETCH_PEOPLE
} from '../actions/types';
const INITIAL_STATE = { people:[], selectedPeople:[]};
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case FETCH_PEOPLE:
return {...state, people: action.payload.data};
case SELECT_PERSON:
return [action.payload, ...state ];
case DESELECT_PERSON:
return _.without({state, selectedPeople:action.payload});
}
return state;
}
The selectedPeople state should add/subtract the id's based on each case. As of now, everytime I deselect the id, my whole "people" table disappears.
You should return the complete state from the reducer in all cases, so:
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case FETCH_PEOPLE:
return {...state, people: action.payload.data};
case SELECT_PERSON:
return {...state, selectedPeople: [ ...state.selectedPeople, action.payload]};
case DESELECT_PERSON:
return {...state, selectedPeople: _.without(state.selectedPeople, action.payload)};
default
return state;
}
}
Also note you didn't have a DESELECT_PERSON action, but instead 2 SELECT_PERSON actions. Possibly a typo.

Resources