0
votes

I have a react component being rendered client side using react router. I have a redux store that is being successfully populated after a dispatch (thus I believe the action and reducer are working correctly)

The problem comes when the connect mapStateToProps function fires, the state is empty.

I have subscribed to the store and console.log(store.getState()) and I can see the state getting set correctly.

Where am I going wrong?

class MyComponent extends Component {

componentWillMount(){

    this.props.fetchData();

}
render(){
  console.log(this.props);
  return(<div>{this.props}</div>
}

const mapStateToProps = (state) => {
console.log(state); //This is empty e.g. { form : {} }
return {
    formJSON: state.form
}
};

const mapDispatchToProps = { fetchData};

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

The react router stuff

class ClientApp extends Component {


render() {
    return (
      <Provider store={store}>
        <Router history={history}>
          <Switch>
            <Route exact path="/" >
              <div>Root</div>
            </Route>
            <Route path='/mycomponent'>
              <Container fluid>
                <Row>
                  <Col lg={2}>
                    <MyComponent/>
                  </Col>
                  <Col lg={7}>
                    <OtherComponent />
                  </Col>
                  <Col>
                    <YetAnotherComponent/>
                  </Col>
                </Row>
              </Container>
            </Route>
          </Switch>
        </Router>
      </Provider>      
    );
  }
}

export default ClientApp;
1
You can check the devtools and see if you select the correct data from the state. If you want to dump a js object in jsx you can do: return(<pre>{JSON.stringify(this.props,undefined,2)}</pre>HMR
I cannot install devtools sadly as I am blocked by policy. I did already state what was in the state. It is { form: {} }, ie the form is empty. I would expect data here. If I look at the state in the store using the subscribe method then it is correctly populated. My question is why is an empty (or initial) state being passed to the connect component?Charlie Benger-Stevenson
With some strategic console.logs I have managed to narrow down the problem a bit. What I can say is that the store state is initialised, and then further set by the dispatch. The connect component fires the mapStateToProps only once on initialise but not when the dispatch updates the state. This is why my props are empty / in the initial state. Any ideas anyone why the mapStateToProps function isn't being called?Charlie Benger-Stevenson
I installed redux-logger and I have confirmed the action, dispatch and reducer are working correctly. This is the connect component misbehaving / incorrectly set up...Charlie Benger-Stevenson
You are probably mutating state in the reducer so the connect is never fired because react-redux did not notice any change.HMR

1 Answers

-1
votes

Can you try this:

import React from "react";
import "./cart-icon.styles.scss";
import { connect } from "react-redux";
import { fetchData } from "path for fetchData";

class MyComponent extends Component {
constructor(props){
super(props);
this.state={
formJSON:{}
 }
}

componentDidMount(){
    this.props.fetchData();
}

componentDidUpdate(prevProps){
   if(prevProps.formJSON !==this.props.formJSON){
     this.setState({formJSON})
  }
}

render(){
  console.log(this.state.formJSON);
  return(<div>{this.state.formJSON}</div>
}}

const mapStateToProps = ({form}) => ({
  formJSON:form
});

const mapDispatchToProps = (dispatch) => ({
  fetchData: () => dispatch(fetchData()),
});

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