reactjs - 使用模式框在 React 中编辑项目后重新加载列表 - 将功能从一个组件传递到另一个组件
问题描述
我在一个 CRUD 表中工作,为此我创建了 2 个文件,一个列出该表,另一个用于编辑列表中的每个项目。我正在使用模态进行编辑或创建。
与 api 和数据库的交互工作正常。但是有两个问题正在发生。
点击CategoryForm文件中的Button Submit后,modal没有关闭,还是打开了,不知道怎么把这个函数从list传给form。并从那里使用它。
该表不会重新加载插入数据的新行。(数据正确地进入 api 和数据库)。还认为需要将它从列表组件传递到表单并从那里调用它。
提前致谢。我不知道拥有两个包含两个组件的文件是否是最好的解决方案,所以我愿意接受建议。
这是名为Categories.jsx的列表文件
import React, { Component } from 'react'
import { Alert, Modal, Button } from "react-bootstrap";
import Datatable from '../../../globalcomponents/datatable/Datatable';
import CategoryForm from './CategoryForm';
import { FaPencilAlt,FaTrashAlt } from 'react-icons/fa';
const Api = require('../../api/CategoriesApi.js')
class Categories extends Component {
constructor(props) {
super(props)
this.state = {
categories: [],
isLoaded: false,
error: null,
isOpen: false,
id: null
}
}
openModal = (id) => {
this.setState( (prev) => {
const state = prev.state;
return { ...state, id: id, isOpen:true };
});
};
closeModal = () => this.setState({ isOpen: false });
componentDidMount() {
Api.getCategories()
.then(response => {
const [error, data] = response
if (error) {
this.setState({
isLoaded: true,
categories: [],
error: data
})
} else {
this.setState({
isLoaded: true,
categories: data
})
}
})
}
removeCategory = (id) => {
var categories = [...this.state.categories];
var index = categories.findIndex(function(item, i){return item.id === id})
categories.splice(index, 1);
this.setState({categories});
Api.deleteCategory(id)
}
render() {
const { error, isLoaded, categories } = this.state
if (error) {
return (
<Alert color="danger">
Error: {error}
</Alert>
)
} else if (!isLoaded) {
return (
<Alert color="primary">
Loading...
</Alert>
)
} else {
return (
<>
<Button
className="float-right"
variant="primary"
onClick={e => this.openModal()}
>
Adicionar
</Button>
<h4 className="mt-4 mb-4">Categorias de investimentos</h4>
<Datatable>
<table className="table table-striped my-4 w-100">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Url (Slug)</th>
<th></th>
</tr>
</thead>
<tbody>
{categories.map(category => (
<tr key={category.id}>
<td>{category.id}</td>
<td>{category.title}</td>
<td>{category.slug}</td>
<td>
<Button
className="btn btn-danger float-right"
onClick={(event) =>
this.removeCategory(category.id)
}
><FaTrashAlt /></Button>
<Button
className="btn btn-success float-right mr-2 "
onClick={() =>this.openModal(category.id)}
>
<FaPencilAlt />
</Button>
</td>
</tr>
))}
</tbody>
</table>
</Datatable>
<Modal show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>Adicionar / Editar</Modal.Title>
</Modal.Header>
<Modal.Body>
<CategoryForm id={this.state.id || null}/>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
)
}
}
}
export default Categories
这是表单文件:
import React, { Component } from 'react'
import { Redirect } from 'react-router'
import { Row, Col, Alert, Button, Form, FormGroup, Label, Input } from 'reactstrap'
const Api = require('../../api/CategoriesApi.js')
class CategoryForm extends Component {
constructor(props) {
super(props)
this.state = {
category: {
id: this.getCategoryId(props),
title: '',
slug: '',
},
redirect: null,
errors: [],
reload: false
}
this.setTitle = this.setTitle.bind(this)
this.setSlug = this.setSlug.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
getCategoryId(props) {
try {
return props.id
} catch (error) {
return null
}
}
setTitle(event) {
let newVal = event.target.value || ''
this.setFieldState('title', newVal)
}
setSlug(event) {
let newVal = event.target.value || ''
this.setFieldState('slug', newVal)
}
setFieldState(field, newVal) {
this.setState((prevState) => {
let newState = prevState
newState.category[field] = newVal
return newState
})
}
handleSubmit(event) {
event.preventDefault()
let category = {
title: this.state.category.title,
slug: this.state.category.slug,
}
Api.saveCategory(category, this.state.category.id)
.then(response => {
const [error, errors] = response
if (error) {
this.setState({
errors: errors
})
} else {
this.setState(
() => this.setState({reload: true})
)
}
})
}
componentDidMount() {
if (this.props.id ) {
Api.getCategory(this.props.id).then((response) => {
const [error, data] = response;
if (error) {
this.setState({
errors: data
});
} else {
this.setState({
category: data,
errors: []
});
}
});
}
}
render() {
const { redirect, category, errors } = this.state
if (redirect) {
return (
<Redirect to={redirect} />
)
} else {
return (
<>
<Row>
<Col>
{errors.length > 0 &&
<div>
{errors.map((error, index) =>
<Alert color="danger" key={index}>
{error}
</Alert>
)}
</div>
}
<Form onSubmit={this.handleSubmit}>
<FormGroup>
<Label for="title">Title</Label>
<Input type="text" name="title" id="title" value={category.title} placeholder="Enter title" onChange={this.setTitle} />
</FormGroup>
<FormGroup>
<Label for="slug">Slug</Label>
<Input type="text" name="slug" id="slug" value={category.slug} placeholder="Enter slug" onChange={this.setSlug} />
</FormGroup>
<Button color="success">Submit</Button>
</Form>
</Col>
</Row>
</>
)
}
}
}
export default CategoryForm
解决方案
在一个地方你在另一个地方const [error, data] = response
,const [error, errors] = response
这是故意的吗?
您没有为关闭模式传递任何 cb 或将数据更新到<CategoryForm id={this.state.id || null}/>
.
Categories.jsx
组件不知道您何时更新 API 上的数据。
也许像
<CategoryForm id={this.state.id || null}
onSubmit={() => {
closeModal()
Api.getCategories()
.then(...
}}/>`
推荐阅读
- appium-ios - 如何在 iOS 自动化中处理键盘不存在的问题
- node.js - 有没有办法在 React 类组件中使用 Modal
- postgresql - 如何修改 AWS RDS 实例的 max_standby_archive_delay 参数?
- windows-10 - 为什么我从不同平台下载时,智能屏有时只提示?
- azure - 哪些任务可以“复制”/“复制” Azure 数据流中的某些行?
- sql - Postgresql - 在查询中将字段合并到 JSON 对象
- elasticsearch - 是否可以通过 uuid 更新嵌套文件
- java - PrimeNG tabMenu 点击事件将被禁用的选项卡禁用
- r - R(hclust)中的聚类分析:如何确定哪个变量驱动聚类
- javascript - 为什么出现散点图时我的条形图消失了?