【问题标题】:Reactjs frontend gets error when backend runsReactjs 前端在后端运行时出错
【发布时间】:2020-04-16 08:48:00
【问题描述】:

我使用 React Js 作为前端,使用 node express 作为后端。当我使用npm start 启动我的前端时,它运行时没有错误,但是当我也启动我的后端时,它会抛出这个错误:TypeError: Cannot read property 'map' of undefined,我找不到任何解决方案。

这是错误所在的代码:

import React, { Component } from 'react'
import ApiService from "../../service/ApiService";
import SearchField from "./SearchField";

class ListModuleComponent extends Component {

    constructor(props) {
        super(props)
        this.state = {
            modules: [],
            message: null
        }
        this.deleteModule = this.deleteModule.bind(this);
        this.editModule = this.editModule.bind(this);
        this.addModule = this.addModule.bind(this);
        this.reloadModuleList = this.reloadModuleList.bind(this);
    }

    componentDidMount() {
        this.reloadModuleList();
    }

    reloadModuleList() {
        ApiService.fetchModules()
            .then((res) => {
                this.setState({ modules: res.data.result })
            });
    }

    deleteModule(moduleId) {
        ApiService.deleteModule(moduleId)
            .then(res => {
                this.setState({ message: 'Delete successful.' });
                this.setState({ modules: this.state.modules.filter(module => module.id !== moduleId) });
            })

    }

    editModule(id) {
        window.localStorage.setItem("moduleId", id);
        this.props.history.push('/edit-module');
    }

    addModule() {
        window.localStorage.removeItem("moduleId");
        this.props.history.push('/add-module');
    }

    render() {
        return (
            <div>
                <h2 className="text-center">Modul data</h2>
                <button className="btn btn-danger" style={{ width: '100px' }} onClick={() => this.addModule()}>Add</button>
                <SearchField />
                <table className="table table-striped">
                    <thead>
                        <tr>
                            <th className="hidden">Id</th>
                            <th>Id</th>
                            <th>Name</th>
                            {/* <th>Key</th> */}
                            <th>Default value</th>
                            <th>Description</th>
                            <th>State</th>
                        </tr>
                    </thead>
                    <tbody>
                        {
                            this.state.modules.map( // Error throws on this line //
                                module =>
                                    <tr key={module.id}>
                                        <td>{module.moduleName}</td>
                                        <td>{module.moduleDefaultValue}</td>
                                        <td>{module.description}</td>
                                        <td>{module.isActive}</td>
                                        <td>
                                            <button className="btn btn-success" onClick={() => this.deleteModule(module.id)}> Delete</button>
                                            <button className="btn btn-success" onClick={() => this.editModule(module.id)} style={{ marginLeft: '20px' }}>Edit</button>
                                        </td>
                                    </tr>
                            )
                        }
                    </tbody>
                </table>

            </div>
        );
    }

}

export default ListModuleComponent;

所以这个错误只有在我的后端启动时才会出现,我不知道它是由后端还是前端引起的,只看到 React 前端的错误。如果需要,我可以提供更多代码。

【问题讨论】:

  • 您确定res.data.result 返回的是一个实际的数组吗?我的猜测是这个返回undefined
  • 在调用设置状态(如this.setState({ modules: res.data.result }))之前,您必须注销您的 api 响应,因为 res.data.result 未定义,因此您可以有条件地将其设置为该值或将其默认设置为空数组

标签: node.js reactjs express


【解决方案1】:

res.result.data 很可能是undefined。您可以通过两种方式解决此问题:

1。防止在您的状态下未定义。

如果res.result.dataundefined,您可以将状态设置为空数组,如下所示:

this.setState({ modules: res.data.result || [] });

这将确保您的状态始终包含一个数组,即使后端没有提供数据。


2。在呈现数据之前进行空值检查。

在呈现您的内容之前检查您的this.state.modules 是否持有值。

<div>
  {this.state.modules && this.state.modules.map(module => {
    // Code
  }}
</div>

【讨论】:

  • 谢谢这是问题所在,res.result.dataundefined
  • 我可能会更精确地进行空检查,因为他后来指的是非常具体的数组功能。因此我宁愿检查instanceof Array,否则你可以再次调用未定义的函数。
【解决方案2】:

模块的默认状态是一个数组,这意味着对其进行映射是可以的,所以如果它没有获取任何数据,那么组件将正常渲染。

this.state = {
        modules: [],
        message: null
    }

当后端启动后,重新加载模块方法将模块设置为 res.data.result

错误是无法读取未定义的属性“地图”。

因此我认为 res.data.result 是未定义的。

要解决此问题,请检查 res 是什么,并确保您设置的 state 是数据数组

【讨论】:

    【解决方案3】:

    似乎空检查可以解决这里明显的问题。

    {
      this.state.modules instanceof Array && this.state.modules.map(
        module => { /*...*/ }
      )
    }
    

    尽管如此,我强烈认为后端已经正确传递了数据。此外,您的代码假设数组总是在那里,我找不到它已被删除/错误初始化的地方。所以我只是假设后端返回一个未定义/空值,这个检查也将涵盖。因此,也许可以调查您的后端是否返回空值。

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2022-10-17
      • 2018-04-21
      • 2021-05-02
      • 2021-05-03
      • 2023-04-01
      • 2019-06-29
      • 2021-10-16
      • 1970-01-01
      相关资源
      最近更新 更多