【问题标题】:react warning cannot set state when using promises使用承诺时反应警告无法设置状态
【发布时间】:2018-06-12 06:14:46
【问题描述】:

我正在尝试查询服务器以获取导航项目列表,以便我可以在 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"));

这是 IE 错误

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

网络包

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 问题仍然存在。小提琴作品

【问题讨论】:

  • 您在HeaderHomeContent 组件中使用setState,如果是,您可以显示这些组件吗?
  • 我只在 sidebar.js 中使用它,并且在 index.js 中设置为上面粘贴的
  • 是你的API端点/api/user/get/user/method/menu/format/json还是你需要发送headers
  • 我正在从这里检索数据以建立我的菜单列表
  • 查看您的代码后,问题似乎是您将 DOM 元素传递到侧边栏。您能否将您的侧边栏代码添加到您的问题中以供检查?

标签: javascript reactjs webpack promise babel-polyfill


【解决方案1】:

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

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);
      }

【讨论】:

  • 您仍然收到错误“只能更新已安装或正在安装的组件...”?
  • 错误是Failed! TypeError: Cannot set property 'menuList' of undefined
  • 很难说它从这个调试中落下,你可以修复一件事.. menuList.push(${menuitem.link} }>{ menuitem.title }) 。 . 应该是 ${menuitem.link} 周围的反引号(` `)
  • 试试这个:React.createElement("div", { className: "'side-nav-header'" }, menus.title)
  • 您还可以添加执行所有这些逻辑的函数并在 componentDidUpdate 中调用它。这将更容易调试
【解决方案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"));

【讨论】:

  • componentDidMount 是 api 调用和 setstate 的最佳位置,因为它重新渲染客户端
  • 请检查您的回复是否收到?
  • 我的 api 响应正在被接收。问题在于 setState
  • 尝试调试器或控制台在渲染和内部.then 并检查组件是否正在重新渲染。
  • 我在渲染中添加了console.log(this.state.menuList);,它是空数组。
【解决方案3】:

注意:我添加了 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 os ,没有 IE ,所以我没有检查 IE。 我使用索引作为键,因为我没有任何唯一 ID。 请检查您可以将哪些唯一 ID 设置为键。

【讨论】:

  • 对 fiddle 进行了一些更改。 jsfiddle.net/emmwg9Lq/1 菜单现在正在显示。我想告诉你一件事,我对结构不太清楚。什么是 menuData 、 menuList 和您在代码中使用的各种变量。所以试着从小提琴代码中理解并相应地实现。如果您已经创建了 react element ,则无需遍历数组,直接返回它。以更好的方式构建您的代码。制作对一件事负责的干净组件,而不是很多。请参阅我在这里提到的小提琴。
  • 请看这篇文章reallifeprogramming.com/…
  • menuData 是来自返回的 api 调用的子集数据,menuList 是我想在页面上显示的菜单项数组,这些菜单项是通过循环 menuData 而创建的
  • 我注意到在您的链接中 menuList 不是从 Promise 设置的,而是使用默认值。我需要它由 Promise 设置。你能看看这个jsfiddle.net/shorif2000/kzpj5p8m
  • 当我将它复制到我的服务器编译构建运行时,它似乎将每个 ajax 请求发送两次
【解决方案4】:

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

【讨论】:

  • 你能提供示例代码吗,我的问题中有 jsfiddle
  • 这是我更新的小提琴 jsfiddle.net/shorif2000/gabgc28e 它在那里工作正常,但在我的环境中它会抛出该错误并运行两次 api 调用
【解决方案5】:

你会试试这个

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

【讨论】:

    【解决方案6】:

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

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

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

    【讨论】:

      【解决方案7】:

      似乎问题是在不同文件中正确分离代码。我将indexAppcomponentDidMount() 合二为一,但都不起作用。

      我已经完成了

      索引

      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() 现在可以使用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-25
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 2020-11-01
        • 1970-01-01
        • 2019-01-14
        • 2018-01-04
        相关资源
        最近更新 更多