4

[Solved] Check my answers

I'm learning MERN Stack via a youtube playlist https://www.youtube.com/watch?v=TO6akRGXhx8. I'm stuck when i reached the 28:04 where he forgot to connect his component with 'react-redux'. I followed how he resolve it but well, for some reason mine doesn't seem to be connected. No props was pass by to my ItemModal component. So i spent 3hrs to debug and lastly conclude that i found it weird that only when the js is named ShippingList, will connect() works... When I renamed ShippingList to another name and update the references, it doesn't work anymore... Please refer to below for some of the snippet

I dont think i need to identify a component to the store when creating it.. so im stupefied now..

Was wondering if u guys can replicate it, please find my repo https://github.com/AmeDin/mern

ShoppingList.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

export class ShoppingList extends Component {


  render() {
    console.log(this.props)
    console.log(this.state)
    //const { items } = this.props.item;
    return (
      <div>

      </div>
    )
  }
}



const mapStateToProps = (state) => ({
    item: state.item
})

export default connect()(ShoppingList);

ShoppingListOne.js

import React, { Component } from 'react'
import { connect } from 'react-redux';

export class ShoppingListOne extends Component {


  render() {
    console.log(this.props)
    console.log(this.state)
    //const { items } = this.props.item;
    return (
      <div>

      </div>
    )
  }
}



const mapStateToProps = (state) => ({
    item: state.item
})

export default connect()(ShoppingListOne);

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore, applyMiddleware, compose } from 'redux'
import rootReducer from './reducers/index'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import * as serviceWorker from './serviceWorker';

const middleware = [thunk];

const store = createStore(rootReducer, 
    compose(
        applyMiddleware(thunk)
    )
);
ReactDOM.render(<Provider store={store}><App /></Provider>, 
document.getElementById('root'));

serviceWorker.unregister();

Screenshot of console.log: https://i.stack.imgur.com/FPBBs.png

Further testing ShoppingListOne

const mapStateToProps = (state) => ({
    item: state.item
})

const mapDispatchToProps = (dispatch) => {
  console.log(dispatch)

}

export default connect(mapStateToProps, mapDispatchToProps)(ShoppingListOne);

ShoppingList

const mapStateToProps = (state) => ({
    item: state.item
})


const mapDispatchToProps = (dispatch) => {
  console.log(dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(ShoppingList);

No functions seems to be called for ShoppingListOne. ShoppingList has a function called line26, 3rd row of console.

https://i.stack.imgur.com/WxwRm.png

Ame M
  • 65
  • 2
  • 6

3 Answers3

5

You need to pass mapStateToProps function as first argument to connect in order to make these value available to the component connected to redux store . Connect without any arguments don't do anything except make dispatch available as a prop to the connected component

const mapStateToProps = (state) => ({
    item: state.item
})

export default connect(mapStateToProps)(ShoppingListOne);

and

const mapStateToProps = (state) => ({
    item: state.item
})

export default connect(mapStateToProps)(ShoppingList);

Also you need to make sure that you are imported the connected component which is ShoppingListOne exported as a default export rather than a named export

You import would look like

import ShoppingListOne from './path/to/ShoppingListOne';
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Hello, i have perform this test before reaching to the lines below export default connect()(ShoppingListOne); export default connect()(ShoppingList); for further test behaviour. They result in the same way.. im not able to retrieve the state from the store provider in ShoppingListOne, but able to do so in ShoppingList – Ame M Mar 22 '19 at 01:51
  • @AmeM remove the export keyword before `export class ShoppingListOne extends Component {` and import this component as default import – Shubham Khatri Mar 22 '19 at 05:43
  • Kathri, the issue was with the importing component. I do not know the difference between export class vs without 'export'. With or without the 'export', it will work if i import the component without the curly braces '{}'. I'm reading to find out more and understand about importing with '{}' or without it and also finding out the difference between 'export class' vs 'class'. Please enlighten me about it. https://stackoverflow.com/questions/36795819/when-should-i-use-curly-braces-for-es6-import/36796281 – Ame M Mar 22 '19 at 06:07
  • @AmeM, the connected component is returned as a default export and hence you need to import it as a default import without using `{}`. You can read more about this here https://stackoverflow.com/questions/41337709/what-is-use-of-curly-braces-in-es6-import-statement/41338672#41338672 – Shubham Khatri Mar 22 '19 at 06:11
2

You must pass mapStateToProps and mapDispatchToProps to connect, so that it can create a wrapper which has access to redux store.

export default connect(mapStateToProps, mapDispatchToProps)(ShoppingList);
export default connect(mapStateToProps, mapDispatchToProps)(ShoppingListOne);
Prateek Jain
  • 1,504
  • 4
  • 17
  • 27
1

Found out the issue...

The import statement seems to play its role to the connection..

Error

import { ShoppingList } from './components/ShoppingList';
import { ItemModal } from './components/ItemModal';

Correct

import ShoppingList from './components/ShoppingList';
import ItemModal from './components/ItemModal';

Anyone know the differences? Is there a post out there answering it i wonder?

Ame M
  • 65
  • 2
  • 6
  • `import { ShoppingList }` will try to import the property `ShoppingList` from the default export while `import ShoppingList` imports the default export. If, in `ShoppingList.js`, you're doing `export default class ShoppingList` then you would want to import the default export, i.e. `import ShoppingList` – Benjamin Vogler Oct 25 '19 at 06:36