Connected component not receiving store props n Re

2019-02-23 22:32发布

问题:

I was doing a bit of refactoring and tried connecting a higher level component to redux using connect() but the component I'm connecting keeps giving me empty props.

I've included the relevant code, I've structured my redux reducers into a ducks format, so the actions/creators and reducers are in one module file.

The files are containers/login.js, presentation/login.js, presentation/logins.js, app.js and the root index.js.

When I decided to rename some actions, files and reducers, moved the connect to a higher component, the connection stopped working and now I have empty props.

Help much appreciated.

// containers/login.js
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom'
import { fetchPage } from '../redux/modules/Login';
import Login from '../presentation/Login';

const mapStateToProps = (state) => {
  return {
    page: state.page,
    forms: state.forms
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
      fetchPage: () => dispatch(fetchPage())
  } // here we're mapping actions to props
}

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

// redux/modules/login.js
import fetch from 'cross-fetch';

const RECIEVE_FORM = 'RECIEVE_FORM';

export const receiveForm = (response) => ({
  type: RECIEVE_FORM,
  forms: response.forms
})

const initialState = {
  page: "",
  forms: []
}

// MIDDLEWARE NETWORK REQUEST DISPATCHER
export const fetchPage = () => {
  return dispatch => {
    return fetch('http://localhost:3001/login')
    .then(
      response => response.json(),
    )
    .then(
      response => dispatch(receiveForm(response))
    )
  }
}

// REDUCER COMPOSITION CALL EXISTING REDUCERS
// REDUCER COMPOSITION PATTERN
// ACCUMULATIVE ACTION REDUCER
export default function Login(state = initialState, action){
  switch (action.type){
    case RECIEVE_FORM:
    return {
      ...state,
      forms: action.forms
    }
    default:
    return state;
  }
}

// presentation/login.js
import React, { Component } from 'react';
import styled from 'styled-components';
import Wrapper from '../components/Wrapper';
import Card from '../components/Card';
import Text from '../components/Text';
import Logo from '../components/Logo';
import FormGroup from '../components/FormGroup';


const WrapperLogin = styled(Wrapper)`
    .login__card{
        padding: 4.5rem 2.5rem 2rem 2.5rem;
    }
`;

const BoxLogo = styled.div`
    .login__logo{
        display: block;
        margin: 0 auto;
    }
`;

export default class Login extends Component{

  componentDidMount() {
    console.log(this.props)
    //this.props.fetchPage();
  }

    render(){
        return(
            <main>
                <WrapperLogin className="login">
                    <Card className="login__card">
                        <BoxLogo>
                            <Logo className="login__logo" width={187.36} height={76.77} />
                        </BoxLogo>
                        <FormGroup name="login" className="login_formGroup" />
                    </Card>
                    <Text primitive="p" margin='4px 0 0 0' size="0.8rem" textAlign="center" display='block'>Brought to you by WORLDCHEFS</Text>
                </WrapperLogin>
            </main>
        )
    }
}

// app.js
// manage routes here
//import _ from 'lodash';
import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import Login from './presentation/Login';

type Props = {

}

type State = {
  mode: string
};




export default class App extends Component <Props, State> {

  constructor(){
    super();
    this.state = {
      ...this.state,
      mode: 'mobile'
    }
  }

  render(){
    return(
      <ThemeProvider theme={{ mode: this.state.mode }}>
        <Login />
      </ThemeProvider>
    )
  }

}

     // root
    import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import configureStore from './redux/configureStore';
import registerServiceWorker from './registerServiceWorker';
import App from './App';
import { injectGlobal } from 'styled-components';
import styles from './assets/styles';

const store = configureStore();
     ReactDOM.render(
        <Provider store={store}>
        <App />
        </Provider>
        , document.getElementById('root')
    );

回答1:

The reason your props in Login component are empty is because you are not actually using the connected Login container, As you have mentions its in containers/login

So in your App.js change the import of login from ./presentation/login to

import Login from '/path/to/containers/Login';



回答2:

You have imported presentation component in your app.js rather than container component. Please import your container component like below

import Login from './containers/login.js';

This will solve the problem as per my understanding from your code