简体   繁体   中英

Blank page is coming without any error

I know ReactJs but I am new to Redux . I am trying to perform async action like I am calling an API and want to display data received from it. When I am implementing redux in single page, ie actions, reducers, containers all on one page its working fine. Single page code is as follows:

import React from 'react';
import { render } from 'react-dom';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { connect } from 'react-redux';

function fetchPostsRequest(){
  return {
    type: "FETCH_REQUEST"
  }
}

function fetchPostsSuccess(payload) {
  return {
    type: "FETCH_SUCCESS",
    payload
  }
}

function fetchPostsError() {
  return {
    type: "FETCH_ERROR"
  }
}

const reducer = (state = {}, action) => {
  switch (action.type) {
    case "FETCH_REQUEST":
      return state;
    case "FETCH_SUCCESS": 
      return {...state, posts: action.payload};
    default:
      return state;
  }
} 

function fetchPostsWithRedux() {
    return (dispatch) => {
    dispatch(fetchPostsRequest());
    return fetchPosts().then(([response, json]) =>{
        if(response.status === 200){
        dispatch(fetchPostsSuccess(json.data))
      }
      else{
        dispatch(fetchPostsError())
      }
    })
  }
}

function fetchPosts() {
  const URL = "api-url";
  let user = JSON.parse(localStorage.getItem('user'));
  return fetch(URL, {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            api_token: user.api_token,
            type: 'task',
          })
        }).then(response => Promise.all([response, response.json()]));
}

class App extends React.Component {
    componentDidMount(){
    this.props.fetchPostsWithRedux()
  }
    render(){
      return (
            <ul>
                {
            this.props.posts && 
          this.props.posts.map((post,i) =>{
            return(
                <li key={i}>{JSON.parse(post.form_data).title}</li>
            )
          })
        }
        </ul>
    )
  }
}


function mapStateToProps(state){
    return {
    posts: state.posts
  }
}


let Container = connect(mapStateToProps, {fetchPostsWithRedux})(App);

const store = createStore(
    reducer,
    applyMiddleware(thunk)
);
ReactDOM.render(
    <Provider store={store}>
        <Container/>
    </Provider>,
    document.getElementById('app')
);

But when I am trying to make actions, reducers, containers in different files, blank page is coming. There are no errors coming in console, only three warnings as:

  • Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
  • Warning: RouterContext: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.
  • Warning: Automatically setting basename using is deprecated and will be removed in the next major release. The semantics of are subtly different from basename. Please pass the basename explicitly in the options to createHistory.

Store.js code is as follows:

import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import reducer from '../reducers/loginReducer';

const store = createStore(
  reducer,
  applyMiddleware(thunk)
);
var routes =(
    <Provider store={store}>
      <Router history={browserHistory}>
        <Route path="/" component={Main}>
        <Route path="/testing" component={Testing}>
      </Router>
    </Provider>
);

Testing.js code is as:

import React from 'react';
import { render } from 'react-dom';
import ReactDOM from 'react-dom';
import loginContainer from '../containers/loginContainer';

export default class Testing extends React.Component {

    render() {
        console.log("jgkj");
        return (
                <loginContainer />
        );
    }
}
module.exports = Testing;

loginContainer.js code is as follows:

import React, {Component} from 'react';
import {  Link } from 'react-router';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { fetchPostsWithRedux,fetchPosts,fetchPostsError,fetchPostsSuccess,fetchPostsRequest } from '../actions/loginAction';

class loginContainer extends React.Component {
    componentDidMount(){
    this.props.fetchPostsWithRedux()
  }
    render(){
      return (
            <ul>
                {
            this.props.posts && 
          this.props.posts.map((post,i) =>{
            return(
                <li key={i}>{JSON.parse(post.form_data).title}</li>
            )
          })
        }
        </ul>
    )
  }
}


function mapStateToProps(state){
    return {
    posts: state.posts
  }
}
export default connect(mapStateToProps, {fetchPostsWithRedux})(loginContainer);

loginReducer.js code is:

import {
  FETCH_REQUEST,
  FETCH_SUCCESS,
  FETCH_ERROR
} from '../actions/loginAction';

export default function reducer (state = {}, action)  {
  switch (action.type) {
    case "FETCH_REQUEST":
      return state;
    case "FETCH_SUCCESS": 
      return {...state, posts: action.payload};
    default:
      return state;
  }
}

loginAction.js code is as:

export function fetchPostsRequest(){
  return {
    type: "FETCH_REQUEST"
  }
}

export function fetchPostsSuccess(payload) {
  return {
    type: "FETCH_SUCCESS",
    payload
  }
}

export function fetchPostsError() {
  return {
    type: "FETCH_ERROR"
  }
}

export function fetchPostsWithRedux() {
    return (dispatch) => {
    dispatch(fetchPostsRequest());
    return fetchPosts().then(([response, json]) =>{
        if(response.status === 200){
        dispatch(fetchPostsSuccess(json.data))
      }
      else{
        dispatch(fetchPostsError())
      }
    })
  }
}

export function fetchPosts() {
  const URL = "api-url";
  let user = JSON.parse(localStorage.getItem('user'));
  return fetch(URL, {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            api_token: user.api_token,
            type: 'task',
          })
        }).then(response => Promise.all([response, response.json()]));
}

You class loginContainer name begins with a lower case letter which should not be the case, it should begin with a upper case letter for your transpiler, Change to

 import {bindActionCreators} from 'redux';

 class LoginContainer extends React.Component {
    componentDidMount(){
    this.props.fetchPostsWithRedux()
  }
    render(){
      return (
            <ul>
                {
            this.props.posts && 
          this.props.posts.map((post,i) =>{
            return(
                <li key={i}>{JSON.parse(post.form_data).title}</li>
            )
          })
        }
        </ul>
    )
  }
}
function mapStateToProps(state){
    return {
    posts: state.posts
  }
}
function mapDispatchToProps(dispatch) {
     return bindActionCreators({fetchPostsWithRedux: fetchPostsWithRedux}, dispatch)

}
export default connect(mapStateToProps,mapDispatchToProps)(LoginContainer);

Also you are not using dispatch for your actions. Make use of bindActionCreators to bind your action to dispatch

Similarly in Testing.js use

import LoginContainer from '../containers/loginContainer';

export default class Testing extends React.Component {

    render() {
        console.log("jgkj");
        return (
                <LoginContainer />
        );
    }
}
module.exports = Testing;

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