Connect React-Redux Struggling [Object error] {}

Hi, I’m trying to connect Redux and React using the function connect.

I declared Provider, connect, mapState and mapDispatch and the app wrapper (App).

So when I try to render the wrapper component to the DOM

It shows up the error [Object error] {} in the console

How can I fix it?

Here’s the whole code:

You can check the code in CodePen if you wanr clicking here

//--------Global variable number button elements---------//

const buttonBank = [
  {name: 'seven', val: 7},
  {name: 'eight', val: 8},
  {name: 'nine', val: 9},
  {name: 'four', val: 4},
  {name: 'five', val: 5},
  {name: 'six', val: 6},
  {name: 'one', val: 1},
  {name: 'two', val: 2},
  {name: 'three', val: 3},
  {name: 'zero', val: 0},
  {name: 'decimal', val: '.'}
];

//-----------Redux----------------------------//
const add = 'add', subtract = 'subtract', multiply = 'multiply', divide = 'divide', equals = 'equals';

//Actions:
const addOp = number => {
  type: add,
    number
}

const subtractOp = number => {
  type: subtract,
    number
}

const multiplyOp = number => {
  type: multiply,
    number
}

const divideOp = number => {
  type: divide,
    number
}

const equalsOp = number => {
  type: multiply,
    number
}

//Reducer:
const opReducer = (previousState = 0, action) => {
  switch(action.type) {
    case add:
      return previousState + action.number;
      
    case subtract:
      return previousState - action.number;
      
    case multiply:
      return previousState * action.number;
      
    case divide:
      return previousState / action.number;
      
    case equals:
      return previousState;
      
    default:
      return previousState;
  }
}

const store = Redux.createStore(opReducer);




 //---------React Parent Component----------//           

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      display: ''
    }
    this.handleNumber = this.handleNumber.bind(this);
    this.handleClear = this.handleClear.bind(this);
    this.handleOp = this.handleOp.bind(this);
  }
  
  handleNumber(event) {
    this.setState({
      input: this.state.input.concat(event.target.value),
      display: parseFloat(this.state.input.concat(event.target.value))
    });

  }
  
  handleClear() {
        this.setState({
       input: '',
      display: ''
    });
  }
  
  handleOp(event) {
   console.log(this.props.result);
   console.log(this.props['add']);
  this.props[event.target.value](this.state.display)
  }
  
  render() {
    //-------button setup-------//
    
    const rowSetup = (x, y) => {
  let arr = [];
  for(let i = x; i < y; i++) { 
    arr.push(buttonBank[i]);
  }
  return arr;
}
    
    const fRow = rowSetup(0, 3).map(actual => {
      return(
  <button className = 'col col-2.5'
    id = {actual.name}
    value = {actual.val}
    onClick = {this.handleNumber}>
    {actual.val}
    </button>    )});

const sRow = rowSetup(3, 6).map(actual => {
      return(
  <button className = 'col col-2.5'
    id = {actual.name}
    value = {actual.val}
    onClick = {this.handleNumber}>
      {actual.val}
    </button>    )});

const tRow = rowSetup(6, 9).map(actual => {
      return(
  <button className = 'col col-2.5'
    id = {actual.name}
    value = {actual.val}
    onClick = {this.handleNumber}>
      {actual.val}
    </button>    )});

const foRow = rowSetup(9, 11).map(actual =>{
      return(
  <button className = 'col col-2.5'
    id = {actual.name}
    value = {actual.val}
    onClick = {this.handleNumber}>
      {actual.val}
    </button>    )});
    
    return(
      
 <div className= 'container' id='calculator'>
     Francisco L.
     <div id='display'>{this.state.display}</div>
      
     <div id='buttons'>
     <button id='clear' onClick = {this.handleClear}>Clear</button>   
     <div className= 'row'>
         {fRow}
         <button className = 'col col-2.5'
    id = 'add'
    onClick = {this.handleOp}>
    +
    </button> 
     </div>
       
     <div className= 'row'> 
       {sRow}
       <button className = 'col col-2.5'
    id = 'subtract'
    onClick = {this.handleOp}>
    -
    </button> 
     </div>
       
     <div className= 'row'> 
       {tRow}
       <button className = 'col col-2.5'
    id = 'multiply'
    onClick = {this.handleOp}>
    X
    </button> 
     </div>   
       
     <div className='row'>
       {foRow}
        <button className = 'col col-2.5'
    id = 'equals'
    onClick = {this.handleOp}>
    =
    </button>
       
       <button className = 'col col-2.5'
    id = 'divide'
    onClick = {this.handleOp}>
    /
    </button> 
     </div>
       
       </div>  
     </div>    
    );
  }
}

//------------------React-Redux connect-----------------------//
const Provider = ReactRedux.provider;
const connect = ReactRedux.connect;

const mapStateToProps = (state) => ({result: state});

const mapDispatchToProps = (dispatch) => {
  return {
    'add': (num) => {
      dispatch(addOp(num))},
    'subtract': (num) => {
      dispatch(subtractOp(num))},
    'multiply': (num) => {
      dispatch(multiplyOp(num))},
    'divide': (num) => {
      dispatch(divideOp(num))}
    }
     }

const Container = connect(mapStateToProps, mapDispatchToProps)(Calculator);

class App extends React.Component {
  render() {
    return(
    <Provider store={store}>
        <Container />
      </Provider>    
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root')); 

Right off the top, on observation is your action creators. You are using the implicit return for the arrow function. But when the arrow function sees the open curly brace, it assumes it is a code block, so it assumes you mean this:

const addOp = number => {
  type: add,
  number
  return
}

You need to surround it parentheses so JS knows that you are returning an object:

const addOp = number => ({ type: add, number });

Edit.

Changing as you said and at least now the console error it seems fixed. Now just trying to figure it out how to render properly in the DOM.

Any clues why doesn’t render?

Thanks!

Do you have a pen with these changes so I don’t have to type them out?

Doing a little more digging…

The browser console often has more info than the CP “fake” console. I found this error:

Uncaught Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?invariant=130&args[]=undefined&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Going to that link, it says the full message:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Yeah, I see this sometimes when I try to use a component that isn’t defined. It’s usually an incorrect import. But you have no import statements because this is CP. Your components seemed defined so I just started console.logging components until I found that Provider is undefined.

Digging around I found this line:

const Provider = ReactRedux.provider;

Components are PascalCase so this line should be:

const Provider = ReactRedux.Provider;

When I make all those changes, the errors stop and I see a calculator.

Hey!! Thank you so much. Finally I could connect them

1 Like