简体   繁体   中英

Error: 'Objects are not valid as a React child' in a very simple redux app

In this little Redux app i'm trying to make two very simple counters which can operate independently from each other.

At the moment only Counter1 is connected to the store:

const App = connect(mapStateToProps, mapDispatchToProps)(Counter1);

And store is made up from allReducers:

const store = createStore(allReducers, composeEnchancers());

So, i'm getting this:

Uncaught Error: Objects are not valid as a React child (found: object with keys {CounterReducer1, CounterReducer2}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Counter1.

However if i make this:

const store = createStore(CounterReducer1, composeEnchancers());

Everything starts to work fine...

I know that in this case mistake might be very stupid, but i still can't figure out where exactly is it hiding...

Here is my entire code:

     import React from 'react';
     import ReactDOM from 'react-dom';
     import {createStore, bindActionCreators, compose, combineReducers} from 'redux';
     import {Provider, connect} from 'react-redux';




     //REDUCERS-----------------------------------------------------------------

     function CounterReducer1(state=1, action){
         switch(action.type){
         case 'INCREASE1': 
             return state=state+1;
         default: 
             return state;
         }

     }


     function CounterReducer2(state=1, action){
         switch(action.type){
         case 'INCREASE2': 
             return state=state+10;
         default: 
             return state;
         }

     }

     const allReducers = combineReducers({
         CounterReducer1,
         CounterReducer2
     });

     //REDUCERS------------------------------------------------------------------




     //COMPONENT COUNTER1--------------------------------------------------------
     const Counter1 = ({ counter1, BtnClickHandler1 }) => {
         return(
             <div>
                 <button onClick={() => BtnClickHandler1()}>Counter1Button</button>

                 <h2>{counter1}</h2>

             </div>
         );

     };
     //COMPONENT COUNTER1--------------------------------------------------------





     //COMPONENT COUNTER2--------------------------------------------------------
     const Counter2 = ({ counter2, BtnClickHandler2 }) => {
         return(
             <div>
                 <button onClick={() => BtnClickHandler2()}>Counter2Button</button>

                 <h2>{counter2}</h2>

             </div>
         );

     };
     //COMPONENT COUNTER2-------------------------------------------




     //ROOT COMPONENT-----------------------------------------------------------

     const RootComponent = () =>  {
         return (
             <div>
                 <Counter1 />
                 <Counter2 />
             </div>
         );
     };

     //ROOT COMPONENT--------------------------------------------------------




     //CONNECTING COUNTERS TO THE STORE-----------------------------

     const mapStateToProps = (state) => {
         return{
             counter1: state,
             counter2: state
         };
     };

     const mapDispatchToProps = (dispatch) => {
         return {
             BtnClickHandler1: () => dispatch({type: 'INCREASE1'}),
             BtnClickHandler2: () => dispatch({type: 'INCREASE2'})
         };
     };

     const App = connect(mapStateToProps, mapDispatchToProps)(Counter1);

     //CONNECTING COUNTERS TO THE STORE-----------------------------




     //STORE-------------------------------------------------------------------
     const composeEnchancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
     const store = createStore(allReducers, composeEnchancers());
     //STORE-------------------------------------------------------------------





     //RENDERING-----------------------------------------------------------------
     ReactDOM.render(

         <Provider store={store}>
             <App />
         </Provider>, 

         document.getElementById('app'));
     //RENDERING-----------------------------------------------------------------   

You're trying to pass the whole state (the result of combineReducers() ) to each component, which will result in having an object as props. This is fine, of course, but it's not what you want in this case. I'm talking about the following part of the code:

return {
    counter1: state,
    counter2: state
};

If you'd do a console.log(state) right before returning, you would see this:

{CounterReducer1: 1, CounterReducer2: 1}

So in order to fix this, just return the appropriate part of the store to each component:

return {
    counter1: state.CounterReducer1,
    counter2: state.CounterReducer2
};

First and very important concept is you should not mutate state . Update your reducers as:

function CounterReducer1(state=1, action){
     switch(action.type){
     case 'INCREASE1': 
         return state+1;
     default: 
         return state;
     }

 }


 function CounterReducer2(state=1, action){
     switch(action.type){
     case 'INCREASE2': 
         return state+10;
     default: 
         return state;
     }

 }
  1. You have only Counter1 component connected. You can create just one container component that's connected and render multiple presentational components(Counter1 and Counter2). Move you mappings(mapStateToProps/mapDispatchToProps) and connect code in container component and you can pass the counter results as props to this presentational components.

  2. When you combine reducers, if you dont provide any key, the reducer names which you provide are taken as keys. In that case, you have to get the props as below:

return {
   counter1: state.CounterReducer1,
   counter2: state.CounterReducer2
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM