使用promises

时间:2018-01-02 14:24:34

标签: javascript reactjs webpack promise babel-polyfill

我试图查询服务器以获取导航项列表,以便我可以在init上构建我的菜单。到目前为止,我设法在主页上创建一个包含3个内容的静态页面,其中包括标题,侧边栏和内容。侧边栏是不同类型用户的菜单,因此我需要在加载时检索菜单项。

我收到的错误是

  

只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState,replaceState或forceUpdate。这是一个无操作

更新4

所以我将我的api请求移到了index.js文件,并尝试添加comment中提到的条件。现在它只是使用相同的错误呈现Loading...

    import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import 'core-js/fn/promise';

import SideBar from './components/sidebar';
import Header from './components/header';
import HomeContent from './components/home';


function getJSON(url) {
  return get(url).then(JSON.parse);
}

function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.response);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}

class App extends Component {
    constructor(props){
        super(props);
        this.state = {
                        username: '',
                        user,
                        loading1: true ,
                        menuList : [],
                        loading2: true
        };
    }

    componentDidMount() {
        let currentComponent = this;

        getJSON('/api/user/get/user/method/user/format/json?quiet=1').then((response) => {
            //console.log(JSON.stringify(response));
            //currentComponent.state.username = response.body.recordset.record[0].name;
            //currentComponent.state.user = response.body.recordset.record[0];
            currentComponent.setState({
                username: response.body.recordset.record[0].name,
                loading1: false
            });
        }).catch(error => {
            console.log('Error', error);
        });

        getJSON('/api/user/get/user/method/menu/format/json?quiet=1').then((response) => {
            console.log(JSON.stringify(response));
            let menuData = response.body.recordset.record;
            let menuList = [];
            var i = 0;
            menuData.container.forEach(menus => {
                menus.sub_modules.forEach(submenu => {
                    menuList.push(<li className="menu" key={i}>{ submenu.title }</li>);
                    i++
                    if (submenu.menuitem.length) {
                        submenu.menuitem.forEach(menuitem => {
                            menuList.push(<li key={i}><a href={menuitem.link}>{ menuitem.title }</a></li>);
                            i++;
                        })
                    }
                })
            });
            currentComponent.setState({
                menuList: menuList,
                loading2: false
            });
        }).catch(error => {
            console.log("Failed!", error);
            $('#myModalError .modal-body').html(error);
            $('#myModalError').modal('show');
        });
    }

    componentWillUnmount() {}

    render() {
        let content = '';
        console.log(this.state);
        if(this.state.loading1 || this.state.loading2) {
            content = <div>Loading...</div>
        }else{
            content =
                <div id="wrapper" className="toggled">
                    <Header username={this.state.username}/>
                    <SideBar menuList={this.state.menuList}/>
                    <HomeContent />
                </div>

        }
        return <div>
                   {content}
               </div>
    }
};

ReactDOM.render(<App/>,  document.getElementById("app"));

enter image description here

这是IE错误

IE console error

detailed ie error

sidebar.js

import React, { Component } from 'react';

let menuList = [];
class SideBar extends Component {
    constructor(props){
        super(props);
    }

    render () {
        return (
            <div id="sidebar-wrapper" className="hidden-print">
                <ul className="sidebar-nav">
                {this.props.menuList}
                </ul>
            </div>
        );
    }
}

export default SideBar;

我创建了jsfiddle

的WebPack

var HTMLWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

const ExtractTextPlugin = require("extract-text-webpack-plugin");

const extractSass = new ExtractTextPlugin({
    filename: "[name].[contenthash].css",
    disable: process.env.NODE_ENV === "development"
});

module.exports = {
    entry : [__dirname + '/app/index.js'],
    module: {
         rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            } ,
            {
                test: /\.scss$/,
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader"
                }, {
                    loader: "sass-loader",
                }]
            }
        ],
    },
    output: {
        filename: 'transformed.js',
        path: __dirname + '/docs'
    },
    plugins: [
        HTMLWebpackPluginConfig
    ]
}


{
  "name": "ccp-react",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack"
  },
  "private": true,
  "dependencies": {
    "babel-helper-bindify-decorators": "^6.24.1",
    "babel-plugin-lodash": "^3.3.2",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-plugin-syntax-flow": "^6.18.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators": "^6.24.1",
    "babel-plugin-transform-react-display-name": "^6.25.0",
    "babel-plugin-transform-react-jsx": "^6.24.1",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-es2016": "^6.24.1",
    "babel-preset-es2017": "^6.24.1",
    "babel-preset-flow": "^6.23.0",
    "babel-preset-react-optimize": "^1.0.1",
    "babel-preset-stage-1": "^6.24.1",
    "babel-preset-stage-3": "^6.24.1",
    "bootstrap": "^3.3.7",
    "classnames": "^2.2.5",
    "commander": "^2.12.2",
    "create-react-class": "^15.6.2",
    "cross-env": "^5.1.3",
    "gulp": "^3.9.1",
    "hammerjs": "^2.0.8",
    "lodash": "^4.17.4",
    "ng": "0.0.0-rc6",
    "ng-cli": "^0.7.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-icons-kit": "^1.0.7",
    "react-redux": "^5.0.6",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-side-bar": "^0.3.5",
    "react-sidenav": "^2.1.2",
    "redux": "^3.7.2",
    "rxjs": "^5.5.6",
    "systemjs": "^0.20.19",
    "web-animations-js": "^2.3.1",
    "zone.js": "^0.8.19"
  },
  "devDependencies": {
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "^6.0.95",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-react": "^6.24.1",
    "core-js": "^2.5.3",
    "css-loader": "^0.28.8",
    "extract-text-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^2.30.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.3.3",
    "karma-jasmine": "^1.1.1",
    "karma-jasmine-html-reporter": "^0.2.2",
    "node-sass": "^4.7.2",
    "protractor": "~5.1.2",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.19.1",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.4.2",
    "webpack": "^3.10.0",
    "webpack-bundle-analyzer": "^2.8.2",
    "webpack-dev-server": "^2.9.7"
  }
}

setstate问题仍然存在,即使代码与小提琴中的代码相同。小提琴作品

setstate

7 个答案:

答案 0 :(得分:4)

尝试在更新之前检查组件是否已安装:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import SideBar from './components/sidebar';
import Header from './components/header';
import HomeContent from './components/home';

class App extends Component {
    constructor(props){
        super(props);
        this.mountCheck = false;
        this.state = { navlist: [] };
    }

    componentWillMount() {
        this.mountCheck = true;
    }
    componentWillUnmount() {
        this.mountCheck = false;
    }

    componentDidMount() {
         $.get('/api/user/get/user/method/menu/format/json')
        .done(( response ) => this.setState({ navlist: response } ));
    }

    render() {
        return (
            <div>
                <Header />
                <SideBar navlist={this.state.navlist}/>
                <HomeContent />
            </div>
        );
    }
};

ReactDOM.render(<App/>,  document.getElementById("app"));

你也可以添加shouldComponentUpdate来提高性能并减少浪费的渲染,例如:

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.navlist !== nextState.navlist) {
      return true;
    }
    return false;
  }

请参阅https://reactjs.org/docs/optimizing-performance.html

深度比较检查以获得更好的效果结果,您可以将其用于isEqual的lodash:

shouldComponentUpdate(nextProps, nextState) {
        return !isEqual(this.state, nextState);
      }

答案 1 :(得分:2)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import SideBar from './components/sidebar';
import Header from './components/header';
import HomeContent from './components/home';

class App extends Component {
    constructor(props){
        super(props);
        this.state = { navlist: [] };
    }

  componentDidMount() {
         $.get('api/call')
        .then(( response ) => this.setState({ navlist: response } ));
    }

    render() {
        return (
            <div>
                <Header />
                <SideBar navlist={this.state.navlist}/>
                <HomeContent />
            </div>
        );
    }
};

ReactDOM.render(<App/>,  document.getElementById("app"));

答案 2 :(得分:2)

注意:我已经添加了2秒的超时来模拟API调用。所以2秒后会看到结果

const jsonResponse = {
  header: {
    title: "CCP",
    description: "",
    error: true,
    message:
      "Method getMenu Not Implemented in CCP\\Controller\\UserController",
    user: "UddinS2",
    nav: {
      container: [
        {
          title: "Users",
          link: "#",
          theme: "#007c92",
          sub_modules: [
            {
              title: "Getting Started",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "File - CM Template v6.3",
                  link: "/library/templates/FW-LB-CommsMatrix-Template-v6.3.xls"
                },
                {
                  title: "File - Request Access",
                  link: "/library/docs/Requesting_Access_to_CCP.pdf"
                },
                {
                  title: "Video - CCP Promo",
                  link: "/video_ccp.html"
                },
                {
                  title: "Video - CCP Demo",
                  link: "/video_ccp_demo.html"
                },
                {
                  title: "Video - Request Access",
                  link: "/video_request_access.html"
                },
                {
                  title: "Video Tutorials",
                  link: "/video_tutorials.php"
                }
              ]
            },
            {
              title: "General",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "DC Standard Networks",
                  link: "/api/user/dcsn/format/xml"
                },
                {
                  title: "Find Comms Matrix Flow",
                  link: "/find_comms_matrix_flow.php"
                },
                {
                  title: "Find Host",
                  link: "/find_host.php"
                },
                {
                  title: "Find IP Network",
                  link: "/find_network.php"
                },
                {
                  title: "List Comms Matrices",
                  link: "/comms_matrices.php"
                },
                {
                  title: "My Exemption Requests",
                  link: "/api/user/exemption/requests/format/xml"
                },
                {
                  title: "Request Exemption",
                  link: "/request_exemption.php"
                },
                {
                  title: "Services, Projects, ...",
                  link: "/api/user/services/format/xml"
                },
                {
                  title: "View FW Objects",
                  link: "/view_network_service_objects.php"
                },
                {
                  title: "Create Comms Matrix",
                  link: "/create_comms_matrix.php"
                },
                {
                  title: "Comms Matrix Templates",
                  link: "/api/user/commsmatrix/templates"
                },
                {
                  title: "Upload Comms Matrix",
                  link: "/upload_comms_matrix.php"
                },
                {
                  title: "Verify Policy Flow",
                  link: "/verify_policy_flow.php"
                },
                {
                  title: "View Security Policy",
                  link: "/security_zoning_policy.php"
                },
                {
                  title: "View Routing Policy",
                  link: "/routing_domain_policy.php"
                }
              ]
            },
            {
              title: "IP Management",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Adressing Types",
                  link: "/api/user/iam/addressing/types/format/xml"
                },
                {
                  title: "Cramer Ranges (Live)",
                  link: "/api/user/iam/cramer/ranges/format/xml"
                },
                {
                  title: "Cramer Spool Queue",
                  link: "/api/user/cramer/spool/queue/format/xml"
                },
                {
                  title: "Create Subnet",
                  link: "/iam_create_subnet.php"
                },
                {
                  title: "Subnet Types",
                  link: "/api/user/iam/subnet/types/format/xml"
                },
                {
                  title: "Zone Type Sizes",
                  link: "/api/user/security/zone/type/sizes/format/xml"
                },
                {
                  title: "My Network Diagrams",
                  link: "/api/user/iam/network/diagrams/format/xml"
                },
                {
                  title: "My Subnet Requests",
                  link: "/api/user/subnet/requests/format/xml"
                },
                {
                  title: "Range Assignments",
                  link: "/api/user/iam/range/assignments/format/xml"
                },
                {
                  title: "Upload Network Diagram",
                  link: "/iam_upload_diagram.php"
                }
              ]
            },
            {
              title: "Networks",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Entity Networks",
                  link: "/api/user/networks/by/entity/format/xml"
                },
                {
                  title: "Frozen Objects",
                  link: "/api/user/frozen/objects/format/xml"
                },
                {
                  title: "IPBB Metadata",
                  link: "/api/user/ipbb/metadata/format/xml"
                },
                {
                  title: "Map Routing Zones",
                  link:
                    "/api/user/routing/domains/mapping/routingzone/format/xml"
                },
                {
                  title: "NITX Trace",
                  link: "/nitx_trace.php"
                },
                {
                  title: "Routing Domains",
                  link: "/api/user/routing/domains/format/xml"
                },
                {
                  title: "Routing Domain Aliases",
                  link: "/api/user/aliases/routing/domains/format/xml"
                },
                {
                  title: "Routing Domains ACL",
                  link: "/api/user/routing/domains/acl/format/xml"
                },
                {
                  title: "Routing Exemptions",
                  link: "/api/user/routing/exemptions/format/xml"
                }
              ]
            },
            {
              title: "Reporting",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Statistics Dashboard",
                  link: "/statistics_dashboard.php"
                },
                {
                  title: "ECT Statistics",
                  link: "/api/user/connectivity/test/statistics"
                },
                {
                  title: "Exemption Requests",
                  link: "/api/user/report/exemption/requests/format/xml"
                },
                {
                  title: "Exemption Policies",
                  link: "/api/user/report/exemption/policies/format/xml"
                }
              ]
            },
            {
              title: "Security",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Firewall Network Objects",
                  link: "/firewall_network_objects.php"
                },
                {
                  title: "Firewall Service Objects",
                  link: "/firewall_service_objects.php"
                },
                {
                  title: "Local Market Networks",
                  link: "/api/user/networks/opco/format/xml"
                },
                {
                  title: "Security Exemptions",
                  link: "/api/user/exemptions/format/xml"
                },
                {
                  title: "Security Zones",
                  link: "/api/user/security/zones/format/xml"
                },
                {
                  title: "Security Zone Aliases",
                  link: "/api/user/aliases/security/zones/format/xml"
                },
                {
                  title: "Network Zone Aliases",
                  link: "/api/user/aliases/network/zones/format/xml"
                },
                {
                  title: "Map Security Zones",
                  link: "/api/user/security/zones/mapping/seczone/format/xml"
                },
                {
                  title: "Map Network Zones",
                  link: "/api/user/security/zones/mapping/netzone/format/xml"
                },
                {
                  title: "Security Zones ACL",
                  link: "/api/user/security/zones/acl/format/xml"
                }
              ]
            },
            {
              title: "Audit",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Firewall Network Objects",
                  link: "/api/user/audit/firewall/network/objects/format/xml"
                },
                {
                  title: "Firewall Service Objects",
                  link: "/api/user/audit/firewall/service/objects/format/xml"
                },
                {
                  title: "Security Zones",
                  link: "/api/user/audit/security/zones/format/xml"
                },
                {
                  title: "Security Zones ACL",
                  link: "/api/user/audit/security/zones/acl/format/xml"
                },
                {
                  title: "Security Zones Aliases",
                  link: "/api/user/audit/security/zone/aliases/format/xml"
                },
                {
                  title: "Security Zone Mappings",
                  link: "/api/user/audit/security/zone/mapping/format/xml"
                },
                {
                  title: "Network Zone Aliases",
                  link: "/api/user/audit/network/zone/aliases/format/xml"
                },
                {
                  title: "Routing Domains",
                  link: "/api/user/audit/routing/domains/format/xml"
                },
                {
                  title: "Routing Domains ACL",
                  link: "/api/user/audit/routing/domains/acl/format/xml"
                },
                {
                  title: "Routing Domain Aliases",
                  link: "/api/user/audit/routing/domain/aliases/format/xml"
                },
                {
                  title: "Routing Domain Mappings",
                  link: "/api/user/audit/routing/domain/mapping/format/xml"
                }
              ]
            }
          ]
        },
        {
          title: "Site Administration",
          link: "#",
          theme: "#007c92",
          sub_modules: [
            {
              title: "Content Management",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Business Units",
                  link: "/api/user/businessunits/format/xml"
                },
                {
                  title: "Entities",
                  link: "/api/user/entities/format/xml"
                },
                {
                  title: "Locations",
                  link: "/api/user/locations/format/xml"
                },
                {
                  title: "Markets",
                  link: "/api/user/markets/format/xml"
                },
                {
                  title: "Service Domains",
                  link: "/api/user/servicedomains/format/xml"
                }
              ]
            },
            {
              title: "Health Check",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Networks Status",
                  link: "/api/user/networks/status/format/xml"
                }
              ]
            },
            {
              title: "User Management",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Assign Group Privilges",
                  link: "/assign_group_privs.php"
                }
              ]
            },
            {
              title: "Troubleshooting",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Debug Comms Matrix",
                  link: "/debug_comms_matrix.php"
                },
                {
                  title: "Mocha Tests",
                  link: "/testrunner.php"
                }
              ]
            },
            {
              title: "Super Admin",
              link: "#",
              theme: "#007c92",
              menuitem: [
                {
                  title: "Sudo Group Access",
                  link: "/sudo_group_access.php"
                }
              ]
            }
          ]
        }
      ]
    },
    server: 1,
    version: "17.1",
    timestamp: 1514902917
  },
  body: []
};

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      navList: []
    };
  }

  componentDidMount() {
    //$.get('/api/user/get/user/method/menu/format/json')
    //.done ((response) => console.log(response));
    //.done(( response ) => this.setState({ navlist: //response } ));
    //dont have actual api hence setting state with response data mentioned in question
    setTimeout(() => {
      this.setState({
        navList: jsonResponse
      });
    }, 2000);
  }

  componentWillUnmount() {}

  render() {
    //removing header and HomeContent as definition is not there
    return (
      <div>
        <SideBar navlist={this.state.navList} />{" "}
      </div>
    );
  }
}
let SideBar = props => {
  const { navlist } = props;
  let navlistView = null;
  const getMenuItems = menuItemsArray => (
    <ul>
      {"       "}
      {menuItemsArray.map((element, index) => (
        <li key={index}>{element.title} </li>
      ))}
    </ul>
  );
  const getSubMenu = subMenuArray => (
    <div>
      {" "}
      {subMenuArray.map((element, index) => (
        
        <ul key={index}>-- - {element.title}
        { <li>
           {getMenuItems(element.menuitem)}
          </li>
       }
        </ul>
      ))}
    </div>
  );
  const getView = () => {
    let navlistView = null;
    if (navlist.header) {
      const navInfo = navlist.header.nav.container;
      navlistView = navInfo.map((navlist, index) => (
        <div key={index}>
        {navlist.title}
        <div>
        {getSubMenu(navlist.sub_modules)}
        </div>
        </div>
      ));
    }
    return navlistView;
  };

  return (
    <div id="sidebar-wrapper" className="hidden-print">
      {" "}
      {getView()}{" "}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app"></div>

For first error
Failed! TypeError: Cannot read property 'setState' of undefined
issue : callback doesnot have correct context.


Failed! TypeError: Cannot read property 'menuList' of undefined
This is also context issue as getJson is called with new context.

我正在使用linux操作系统,没有IE,所以我没有检查过IE。    我使用索引作为键,因为我没有任何唯一的ID。    请检查您可以设置为密钥的唯一ID。

答案 3 :(得分:0)

setState中有componentDidMount。这会创建一个循环,您的组件将永远自行安装(因为setState最终导致componentDidMount被调用),这就是React阻止它的原因。通过getJSON获得的数据应该只更新状态,而不是传递给React的渲染阶段之一。更新状态后,您的组件应自动重新呈现。 componentDidMount中的大部分逻辑应该在您的render函数中,格式化数据,以便下面的return命令可以使用它。

答案 4 :(得分:0)

你会试试这个

     fetch(url)
        .then((response) => {
               let jsonData=response.json();
               this.setState({data:jsonData})
         })
        .catch((error) => {
               console.log("error---",error);
         })

答案 5 :(得分:0)

我会将get请求的逻辑移到componentWillMount中。 React错误告诉您,只能在“安装组件”中调用promise。然后你可以调用setState。然后在渲染中,您可以根据状态变量有条件地渲染。

{this.state.navList.length &&
         <div>
            <Header />
            <SideBar navlist={this.state.navlist}/>
            <HomeContent />
        </div>}

您还可以在等待数据返回时呈现不同的加载组件。

答案 6 :(得分:0)

似乎问题是在不同的文件中正确分离代码。我的indexApp只有componentDidMount(),其中一个无效。

所以我已经完成了

<强>索引

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { BrowserRouter, Route, browserHistory } from 'react-router-dom';
import promise from 'redux-promise';

import App from './App'
import reducers from './reducers';

require("babel-core/register");
require("babel-polyfill");

const createStoreWithMiddleware = applyMiddleware(promise)(createStore);

ReactDOM.render(
        <Provider store={createStoreWithMiddleware(reducers)}>
            <BrowserRouter history={browserHistory}>
                <App/>
            </BrowserRouter>
        </Provider>
        , document.getElementById('root'));

应用

import React, { Component } from 'react'
import { HashRouter, Switch, Route, Link } from 'react-router-dom';
import Header from './components/header';
import Logout from './components/logout';
import SideBar from './components/sidebar';
import HomeContent from './components/home';
import Ldapuser from './components/ldapuser';
import AdminContent from './components/getting_started/admin';

const Main = () => (
    <main>
     <Switch>
       <Route exact path='/index.html' component={HomeContent}/>
       <Route exact path='/home' component={HomeContent}/>      
       <Route path='/logout' component={Logout}/>
       <Route path='/ldapuser' component={Ldapuser}/>
       <Route path='/admin/content' component={AdminContent}/>
     </Switch>
    </main>
)

class App extends Component {

    render() {
        return (
            <div>
                <Header />
                <SideBar />
                <Main />
             </div>
        );
    }
}

export default App;

并且单个文件... header等将具有componentDidMount(),现在可以使用