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