Reactjs 如何在提交父组件中的表单时更新子组件

Reactjs 如何在提交父组件中的表单时更新子组件,reactjs,Reactjs,嗨,我已经在这两天了,没有得到任何解决方案或答案。这让我感到紧张和沮丧 我试图做的是在我点击submit后更新子组件中的列表,并将该帖子提交给api服务器上的db。子组件将打印数据库中所有记录的列表。当我提交时,子级应该重新呈现该列表,包括刚刚提交的DB中的所有记录。 我必须点击页面刷新来更新列表,包括新发布的记录。我不想刷新页面。只有列表(子)组件 我尝试了Stackoverflow、Google等所有可能的解决方案 我在用React 16.10 请参阅下面的完整代码。告诉我我需要做什么改变才

嗨,我已经在这两天了,没有得到任何解决方案或答案。这让我感到紧张和沮丧

我试图做的是在我点击submit后更新子组件中的列表,并将该帖子提交给api服务器上的db。子组件将打印数据库中所有记录的列表。当我提交时,子级应该重新呈现该列表,包括刚刚提交的DB中的所有记录。 我必须点击页面刷新来更新列表,包括新发布的记录。我不想刷新页面。只有列表(子)组件

我尝试了Stackoverflow、Google等所有可能的解决方案

我在用React 16.10

请参阅下面的完整代码。告诉我我需要做什么改变才能让它工作

我头痛。在我发布这些问题后,我会得到泰诺

我将从app.js开始:

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

import './App.css';
import Navigation from './components/Navigation';
import TaskList from './components/tasklist';
import EditTask from './components/listEdit';
import CreateList from './components/listCreate';

class App extends Component {
  render() { 
    return (
      <Router>
        <div>
          <Navigation />
          <div className="container">
            <Route path="/" exact component={TaskList} />
            <Route path="/edit/:id" component={EditTask} />
            <Route path="/create" component={CreateList} />
          </div>
        </div>
      </Router>
    );
  }
}

export default App;
以下是我在GitHub上的回购协议:

(后端)
(前端)

将更新的道具传递给子组件时,子组件将重新渲染。否则它就不需要更新

查看您的配置,子组件只有一个道具,并且它从不更改。此外,从API中实际检索更新数据的唯一时间是在
componentDidMount()
中,它仅在首次装入组件后触发

为了使您的功能按预期工作,您需要在每次提交表单时传递更新的道具。收到更新后,向API发出新请求

在不过度重构代码的情况下,我们可以执行以下操作:

在CreateList.js(父项)中:

import React,{Component}来自'React';
从“/TaskList”导入任务列表;
从“axios”导入axios;
导出默认类CreateList扩展组件{
建造师(道具){
超级(道具);
this.onChangeListStatus=this.onChangeListStatus.bind(this);
this.onChangeListItem=this.onChangeListItem.bind(this);
this.onChangeListDue=this.onChangeListDue.bind(this);
this.onSubmit=this.onSubmit.bind(this);
此.state={
新项目:{},
列表\u状态:“”,
列表项:“”,
列表\u到期日:“”,
已创建列表“”“”
}
}
onChangeListStatus(e){
这是我的国家({
列表状态:e.target.value
});
}
onChangeListItem(e){
这是我的国家({
列表项:e.target.value
});
}
onChangeListDue(e){
这是我的国家({
列表到期日:e.target.value
});
}
提交(e){
e、 预防默认值();
log(`Form submitted:`);
log(`itemstatus:${this.state.list_Status}`);
log(`Item:${this.state.list_Item}`);
log(`Item Due:${this.state.list_Due}`);
常量newItem={
列表_状态:this.state.list_状态,
列表项:this.state.list项,
list\u due:this.state.list\u due,
};
轴心柱http://localhost:4000/lists/add,新项目)
。然后(res=>{
这是我的国家({
列表\u状态:“”,
列表项:“”,
列表\u到期日:“”,
新建项目:新建项目
})
});
}
render(){
返回(
创建新项目
新项目:
到期日:
地位:
)
}
}
因此,我们有一个newItem对象,它被传递给子对象。我们只是用它来确定一个变化

taskList.js(子项)

import React,{Component}来自'React';
从“/ItemRow”导入ItemRow;
从“/ItemField”导入ItemField;
从“axios”导入axios;
导出默认类任务列表扩展组件{
建造师(道具){
超级(道具);
this.state={refreshlist:'',
名单:[]
};
}
componentDidMount(){
axios.get()http://localhost:4000/lists/')
。然后(响应=>{
this.setState({lists:response.data});
})
.catch(函数(错误){
console.log(错误);
})
}
componentDidUpdate(prevProps){
if(prevProps.newItem!==此.props.newItem){
axios.get()http://localhost:4000/lists/')
。然后(响应=>{
this.setState({lists:response.data});
})
.catch(函数(错误){
console.log(错误);
})
}
}
listoftask(){
返回此.state.lists.map(函数(currentItem,i){
回来
})
}
render(){
返回(
{this.listoftask()}
)
}
}

在子组件中,我们引入了
componentdiddupdate()
钩子,每当子组件获得更新的道具或状态时,就会触发该钩子。然后,我们只需重新应用您在
componentDidMount()
中使用的相同逻辑来获取列表数据。

读取它。这是有道理的。但当我把它放进我的代码并运行它时。没有变化。列表仍然没有更新。我现在明白了使用
componentdiddupdate()
进行状态更改以触发up
import React, { Component } from 'react';
import TaskList from './tasklist';
import axios from 'axios';

export default class CreateList extends Component {

    constructor(props) {
        super(props);

        this.onChangeListStatus = this.onChangeListStatus.bind(this);
        this.onChangeListItem = this.onChangeListItem.bind(this);
        this.onChangeListDue = this.onChangeListDue.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            list_status: '',
            list_item: '',
            list_due: '',
            list_created: ''
        }
    }

    onChangeListStatus(e) {
        this.setState({
            list_status: e.target.value
        });
    }

    onChangeListItem(e) {
        this.setState({
            list_item: e.target.value
        });
    }

    onChangeListDue(e) {
        this.setState({
            list_due: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();

        console.log(`Form submitted:`);
        console.log(`Item Status: ${this.state.list_status}`);
        console.log(`Item: ${this.state.list_item}`);
        console.log(`Item Due: ${this.state.list_due}`);

        const newItem = {
            list_status: this.state.list_status,
            list_item: this.state.list_item,
            list_due: this.state.list_due,
        };

        axios.post('http://localhost:4000/lists/add', newItem)
            .then(res => console.log(res.data));

        this.setState({
            list_status: '',
            list_item: '',
            list_due: '',
        })
    }

    render() {
        return (
            <div>
            <div style={{marginTop: 10}}>
                <h3>Create New Item</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group"> 
                        <label>New Item: </label>
                        <input  type="text"
                                className="form-control"
                                value={this.state.list_item}
                                onChange={this.onChangeListItem}
                                />
                    </div>
                    <div className="form-group">
                        <label>Due Date: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.list_due}
                                onChange={this.onChangeListDue}
                                />
                    </div>
                    <div className="form-group">
                        <label>Status: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.list_status}
                                onChange={this.onChangeListStatus}
                                />
                    </div>        
                    <div className="form-group">
                        <input type="submit" value="Create Item" className="btn btn-primary" />
                    </div>
                </form>
            </div>
            <TaskList reload={"true"}/>
            </div>
        )
    }
}
import React, { Component } from 'react';
import ItemRow from './itemRow';
import ItemField from './itemField';
import axios from 'axios';

export default class TaskList extends Component {

    constructor(props) {
        super(props);
        this.state = {  refreshlist: '',
                        lists: []
                    };
    }

    componentWillReceiveProps(nextProps) {
        this.setState({ data: nextProps.data });  
      }

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

    // componentWillReceiveProps(props) {
    //     this.setState(this.state)
    //   }

    static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.total !== prevState.total) {
          return (this.setState({ refreshlist: nextProps.refreshlist })) // <- this is setState equivalent
        }
        // etc...
      }


    listoftask() {
        return this.state.lists.map(function(currentItem, i){
            return <ItemRow list={currentItem} key={i} />;
        })
    }

    render() {
        return (
            <div>
                <table className="table table-striped" style={{ marginTop: 20 }} >
                    <thead>
                        <ItemField />
                    </thead>
                    <tbody>
                        { this.listoftask() }
                    </tbody>
                </table>
            </div>
        )
    }
}
// const dotenv = require("dotenv"); 
import dotenv from 'dotenv';
import express from 'express';
import cors from 'cors';
// import uuidv4 from 'uuid/v4';
import mongoose from 'mongoose';

const app = express();
const listRoutes = express.Router();

dotenv.config();

const PORT = process.env.PORT || 4000;
const URI_lists = 'mongodb://localhost:27017/lists';

let List = require('./models/task');

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({
    extended: true
}));

mongoose.connect(URI_lists, 
                {useNewUrlParser: true,
                 useUnifiedTopology: true},
                )
        .then(() => {
            console.log("MongoDB database initial connection established successfully.");
        })
        .catch((err) => {
            console.log("ERROR! Could not connect to Database!");
            console.log(err);
        });

const connection = mongoose.connection;
connection.on('disconnected',()=> {console.log('lost connection!')});
connection.on('reconnected',()=> {console.log('reconnected to db again!')});


listRoutes.route('/').get(function(req, res) {
    List.find(function(err, lists) {
        if (err) {
            console.log(err);
        } else {
            res.json(lists);
        }
    });
});

listRoutes.route('/:id').get(function(req, res) {
    let id = req.params.id;
    List.findById(id, function(err, list) {
        res.json(list);
    });
});

listRoutes.route('/update/:id').post(function(req, res) {
    List.findById(req.params.id, function(err, list) {
        if (!list)
            res.status(404).send("data is not found");
        else
            list.list_item = req.body.list_item;
            list.list_status = req.body.list_status;
            list.list_due = req.body.list_due;
            list.list_created = req.body.list_created;

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

listRoutes.route('/add').post(function(req, res) {
    let newitem = new List(req.body);
    newitem.save()
        .then(list => {
            res.status(200).json({'list': 'list item added successfully'});
        })
        .catch(err => {
            res.status(400).send('adding new list item failed');
        });
});

app.use('/lists', listRoutes);

app.listen( PORT, () => { 
    console.log('Server is running on Port: ' + PORT);
});
import React, { Component } from 'react';
import TaskList from './tasklist';
import axios from 'axios';

export default class CreateList extends Component {

    constructor(props) {
        super(props);

        this.onChangeListStatus = this.onChangeListStatus.bind(this);
        this.onChangeListItem = this.onChangeListItem.bind(this);
        this.onChangeListDue = this.onChangeListDue.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            new_item: {},
            list_status: '',
            list_item: '',
            list_due: '',
            list_created: ''
        }
    }

    onChangeListStatus(e) {
        this.setState({
            list_status: e.target.value
        });
    }

    onChangeListItem(e) {
        this.setState({
            list_item: e.target.value
        });
    }

    onChangeListDue(e) {
        this.setState({
            list_due: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();

        console.log(`Form submitted:`);
        console.log(`Item Status: ${this.state.list_status}`);
        console.log(`Item: ${this.state.list_item}`);
        console.log(`Item Due: ${this.state.list_due}`);

        const newItem = {
            list_status: this.state.list_status,
            list_item: this.state.list_item,
            list_due: this.state.list_due,
        };

        axios.post('http://localhost:4000/lists/add', newItem)
             .then(res => {
                 this.setState({
                     list_status: '',
                     list_item: '',
                     list_due: '',
                     new_item: newItem
                 })
             });
    }

    render() {
        return (
            <div>
            <div style={{marginTop: 10}}>
                <h3>Create New Item</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group"> 
                        <label>New Item: </label>
                        <input  type="text"
                                className="form-control"
                                value={this.state.list_item}
                                onChange={this.onChangeListItem}
                                />
                    </div>
                    <div className="form-group">
                        <label>Due Date: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.list_due}
                                onChange={this.onChangeListDue}
                                />
                    </div>
                    <div className="form-group">
                        <label>Status: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.list_status}
                                onChange={this.onChangeListStatus}
                                />
                    </div>        
                    <div className="form-group">
                        <input type="submit" value="Create Item" className="btn btn-primary" />
                    </div>
                </form>
            </div>
            <TaskList newItem={this.state.new_item}/>
            </div>
        )
    }
}
import React, { Component } from 'react';
import ItemRow from './itemRow';
import ItemField from './itemField';
import axios from 'axios';

export default class TaskList extends Component {

    constructor(props) {
        super(props);
        this.state = {  refreshlist: '',
                        lists: []
                    };
    }

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

    componentDidUpdate(prevProps){
         if(prevProps.newItem !== this.props.newItem){
            axios.get('http://localhost:4000/lists/')
                .then(response => {
                     this.setState({ lists: response.data });
                })
                .catch(function (error){
                     console.log(error);
                })
         }
    }

    listoftask() {
        return this.state.lists.map(function(currentItem, i){
            return <ItemRow list={currentItem} key={i} />;
        })
    }

    render() {
        return (
            <div>
                <table className="table table-striped" style={{ marginTop: 20 }} >
                    <thead>
                        <ItemField />
                    </thead>
                    <tbody>
                        { this.listoftask() }
                    </tbody>
                </table>
            </div>
        )
    }
}