首页 > 解决方案 > 如何修复“无法对未安装的组件执行 React 状态更新”?

问题描述

我正在构建一个 TODO 列表,它需要做的一件事就是删除。这是我的 server.js 代码

const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const cpdRoutes = express.Router();
const PORT = 4000;

let Cpd = require("./cpd.model");

app.use(cors());
app.use(bodyParser.json());

//connects my backend to my mongo database
mongoose.connect('mongodb://127.0.0.1:27017/cpds', { useNewUrlParser: true });
const connection = mongoose.connection;

connection.once('open', function() {
    console.log("MongoDB database connection established successfully");
})

cpdRoutes.route('/').get(function(req, res) {
    Cpd.find(function(err, cpds) {
        if (err) {
            console.log(err);
        }
        else {
            res.json(cpds);
        }
    });
});

//finds the data by id
cpdRoutes.route('/:id').get(function(req, res) {
    let id = req.params.id;
    Cpd.findById(id, function(err, cpd) {
        res.json(cpd);
    });
});

//creating data
cpdRoutes.route('/add').post(function(req, res) {
    let cpd = new Cpd(req.body);
    cpd.save()
        .then(cpd => {
            res.status(200).json({'cpd': 'New data added successfully'});
        })
        .catch(err => {
            res.status(400).send('Adding new data failed');
        });
});

//update data
cpdRoutes.route('/update/:id').post(function(req, res) {
    Cpd.findById(req.params.id, function(err, cpd) {
        if (!cpd)
            res.status(404).send("data is not found");
        else
            cpd.cpd_date = req.body.cpd_date;
            cpd.cpd_activity = req.body.cpd_activity;
            cpd.cpd_hours = req.body.cpd_hours;
            cpd.cpd_learningStatement = req.body.cpd_learningStatement;

            cpd.save().then(cpd => {
                res.json('Data updated!');
            })
            .catch(err => {
                res.status(400).send("Update not possible");
            });
    });
});

// cpdRoutes.route('/delete/:id').post(function(req, res) {
//     Cpd.findById(req.params.id, function(err, cpd) {
//         if (!cpd)
//             res.status(404).send("data is not found");
//         else
//             cpd.cpd_date = req.body.cpd_date;
//             cpd.cpd_activity = req.body.cpd_activity;
//             cpd.cpd_hours = req.body.cpd_hours;
//             cpd.cpd_learningStatement = req.body.cpd_learningStatement;

//             cpd.save().then(cpd => {
//                 res.json('Data updated!');
//             })
//             .catch(err => {
//                 res.status(400).send("Update not possible");
//             });
//     });
// });

cpdRoutes.route.get('/delete', function(req, res){
    var id = req.query.id;
    Cpd.find({_id: id}).remove().exec(function(err, expense) {
     if(err)
      res.send(err)
     res.send('Data successfully deleted!');
    })
});

app.use('/cpds', cpdRoutes);

app.listen(PORT, function() {
    console.log("Server is running on Port: " + PORT);
});

我的删除组件:

import React from 'react';
import axios from 'axios';
import { Button } from 'react-bootstrap';
import { Link } from 'react-router-dom';


class DeleteCpd extends React.Component {
    constructor(){
        super();
            this.state={id:''};
            this.onClick = this.onClick.bind(this);
            this.delete = this.delete.bind(this);
    }

    // componentDidMount() {
    //     this.setState({
    //     id: this.props.cpds.id
    //     })
    // }
    componentDidMount() {
        axios.get('http://localhost:4000/cpds/'+this.props.match.params.id)
            .then(response => {
                this.setState({
                    cpd_date: response.data.cpd_date,
                    cpd_activity: response.data.cpd_activity,
                    cpd_hours: response.data.cpd_hours,
                    cpd_learningStatement: response.data.cpd_learningStatement
                })   
            })
            .catch(function (error) {
                console.log(error);
            })
    }

    onClick(e){
        this.delete(this);
    }

    delete(e){
        axios.get('http://localhost:4000/cpds/'+this.props.match.params.id)
        .then(function(response) {

        });
    }

    render(){
    return (
        <Button onClick={this.onClick}>
            <Link to={{pathname: '/', search: '' }} style={{ textDecoration: 'none' }}>
                <span className="glyphicon glyphicon-remove"></span>
            </Link>
        </Button>
    )
    }
}

export default DeleteCpd;

和我的 App.js:

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

import "bootstrap/dist/css/bootstrap.min.css";

import CreateCpd from "./components/create-cpd.component";
import EditCpd from "./components/edit-cpd.component";
import CpdsList from "./components/cpds-list.component";
import DeleteCpd from "./components/cpds-delete.component";

class App extends Component {
  render() {
    return (
      <Router>
        <div className="container">
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <Link to="/" className="navbar-brand">MERN-Stack Cpd tracker App</Link>
            <div className="collpase navbar-collapse">
              <ul className="navbar-nav mr-auto">
                <li className="navbar-item">
                  <Link to="/" className="nav-link">Data List</Link>
                </li>
                <li className="navbar-item">
                  <Link to="/create" className="nav-link">Create Cpd data</Link>
                </li>
              </ul>
            </div>
          </nav>
          <br/>
          <Route path="/" exact component={CpdsList} />
          <Route path="/edit/:id" component={EditCpd} />
          <Route path="/delete/:id" component={DeleteCpd} />
          <Route path="/create" component={CreateCpd} />
        </div>
      </Router>
    );
  }
}

export default App;

这是我得到的错误:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in CpdList (created by Context.Consumer)

我想要做的是通过 id 删除。我究竟做错了什么?

这是我的 CPDList:

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
// import { CSVLink } from "react-csv";
// import DeleteCpd from './cpd_delete.component';

const Cpd = props => (
    <tr>
        <td>{props.cpd.cpd_date}</td>
        <td>{props.cpd.cpd_activity}</td>
        <td>{props.cpd.cpd_hours}</td>
        <td>{props.cpd.cpd_learningStatement}</td>
        <td>{props.cpd.cpd_evidence}</td>
        <td>
            <Link to={"/edit/"+props.cpd._id}>Edit</Link>
        </td>
        <td>
            <Link to={"/delete/"+props.cpd._id}>Delete(not working yet)</Link>
        </td>
    </tr>
)


export default class CpdList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            cpds: [],
            // csvData:[
            //     {
            //         "date": ""
            //     },
            //     {
            //         "activity": ""
            //     },
            //     {
            //     "hours": ""
            //     },
            //     {
            //     "learningStatement": ""
            //     },
            //     {
            //         "evidence": ""
            //     }
            // ]
        };
    };

    // exportCsv()
    // {
    //     var csvRow=[];
    // }


    componentDidMount() {
        axios.get('http://localhost:4000/cpds/')
            .then(response => {
                this.setState({ cpds: response.data });
            })
            .catch(function (error){
                console.log(error);
        });
    };

    componentDidUpdate() {
        axios.get('http://localhost:4000/cpds/')
        .then(response => {
            this.setState({ cpds: response.data });
        })
        .catch(function (error){
            console.log(error);
    });
    }

    cpdList() {
        return this.state.cpds.map(function(currentCpd, i){
            return <Cpd cpd={currentCpd} key={i} />;
        });
    }

    render() {
        return(
            <div>
                <h3>Cpd Data List</h3>
                    <table className="table table-striped" style={{ marginTop: 20 }} >
                        <thead>
                            <tr>
                                <th>Date</th>
                                <th>Activity</th>
                                <th>Hours</th>
                                <th>Learning Statement</th>
                                <th>Evidence</th>
                            </tr>
                        </thead>
                    <tbody>
                        { this.cpdList() }
                    </tbody>
                </table>

                {/* <CSVLink data={csvData}
                    filename={"db.csv"}
                    color="primary"
                    style={{float: "left", marginRight: "10px"}}
                    className="btn btn-primary"
                        >Download .CSV
                </CSVLink> */}

            </div>
        )
    }
};

请忽略仍在处理的已注释掉的代码。

标签: node.jsreactjsexpressmern

解决方案


推荐阅读