我正在尝试开发一个简单的React应用程序,它具有Crud操作,但是我什至无法列出存储在sql数据库中的对象。我在前端遵循以下示例:https://github.com/only2dhir/react-js-example 然后我继续进行,为我的对象添加了组件。
在我的申请中,我有医生和患者。将患者分配给医生,因此医生可以有一个或多个患者。为此,我创建了我的jsx文件ListCaregiverComponent.jsx:
import React, { Component } from 'react'
import ApiServiceCaregiver from "../../service/ApiServiceCaregiver";
import ApiServicePatient from "../../service/ApiServicePatient";
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
class ListCaregiverComponent extends Component {
constructor(props) {
super(props)
this.state = {
caregivers: [],
patients: [],
message: null
}
this.deleteCaregiver = this.deleteCaregiver.bind(this);
this.editCaregiver = this.editCaregiver.bind(this);
this.addCaregiver = this.addCaregiver.bind(this);
this.reloadCaregiverList = this.reloadCaregiverList.bind(this);
this.reloadPatientList = this.reloadPatientList.bind(this);
}
componentDidMount() {
this.reloadCaregiverList();
this.reloadPatientList();
}
reloadCaregiverList() {
ApiServiceCaregiver.fetchCaregivers()
.then((res) => {
this.setState({caregivers: res.data.result})
});
}
reloadPatientList() {
ApiServicePatient.fetchPatients()
.then((res) => {
this.setState({patients: res.data.result})
});
}
deleteCaregiver(userId) {
ApiServiceCaregiver.deleteCaregiver(userId)
.then(res => {
this.setState({message : 'User deleted successfully.'});
this.setState({caregivers: this.state.caregivers.filter(user => user.id !== userId)});
})
}
editCaregiver(id) {
window.localStorage.setItem("userId", id);
this.props.history.push('/edit-caregiver');
}
addCaregiver() {
window.localStorage.removeItem("userId");
this.props.history.push('/add-caregiver');
}
render() {
return (
<div>
<br></br>
<br></br>
<Typography variant="h4" style={style}>Caregiver Details</Typography>
<br></br>
<br></br>
<Table>
<TableHead>
<TableRow>
<TableCell>Id</TableCell>
<TableCell align="right">Name</TableCell>
<TableCell align="right">Birth Date</TableCell>
<TableCell align="right">Gender</TableCell>
<TableCell align="right">Address</TableCell>
<TableCell align="center">Patients</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.caregivers.map(({ id, name, birthDate, gender, address, patients = [] }) =>(
<TableRow key={id}>
<TableCell component="th" scope="row">
{id}
</TableCell>
<TableCell align="right">{name}</TableCell>
<TableCell align="right">{birthDate}</TableCell>
<TableCell align="right">{gender}</TableCell>
<TableCell align="right">{address}</TableCell>
<TableCell align="right">
<TableRow>
<TableCell align = "right" >Id</TableCell>
<TableCell align = "right" >Name</TableCell>
<TableCell align="right">Birth Date</TableCell>
<TableCell align="right">Gender</TableCell>
<TableCell align="right">Address</TableCell>
<TableCell align="right">Medical Record</TableCell>
</TableRow>
{patients.map(({ id, name, birthDate, gender, address, medicalRecord })=> {
return (
<TableRow key={id}>
<TableCell component="th" scope="row">
{id}
</TableCell>
<TableCell align="right">{name}</TableCell>
<TableCell align="right">{birthDate}</TableCell>
<TableCell align="right">{gender}</TableCell>
<TableCell align="right">{address}</TableCell>
<TableCell align="right">{medicalRecord}</TableCell>
</TableRow>
)
})}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
}
const style ={
display: 'flex',
justifyContent: 'center'
}
export default ListCaregiverComponent;
ListPatientComponent.jsx看起来像这样:
import React, { Component } from 'react'
import ApiServicePatient from "../../service/ApiServicePatient";
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
class ListPatientComponent extends Component {
constructor(props) {
super(props)
this.state = {
patients: [],
message: null
}
this.deletePatient = this.deletePatient.bind(this);
this.editPatient = this.editPatient.bind(this);
this.addPatient = this.addPatient.bind(this);
this.reloadPatientList = this.reloadPatientList.bind(this);
}
componentDidMount() {
this.reloadPatientList();
}
reloadPatientList() {
ApiServicePatient.fetchPatients()
.then((res) => {
this.setState({patients: res.data.result})
});
}
deletePatient(userId) {
ApiServicePatient.deletePatient(userId)
.then(res => {
this.setState({message : 'User deleted successfully.'});
this.setState({patients: this.state.patients.filter(user => user.id !== userId)});
})
}
editPatient(id) {
window.localStorage.setItem("userId", id);
this.props.history.push('/edit-patient');
}
addPatient() {
window.localStorage.removeItem("userId");
this.props.history.push('/add-patient');
}
render() {
return (
<div>
<br></br>
<br></br>
<Typography variant="h4" style={style}>Patient Details</Typography>
<br></br>
<br></br>
<Table>
<TableHead>
<TableRow>
<TableCell>Id</TableCell>
<TableCell align="right">Name</TableCell>
<TableCell align="right">Birth Date</TableCell>
<TableCell align="right">Gender</TableCell>
<TableCell align="right">Address</TableCell>
<TableCell align="right">Medical Record</TableCell>
<TableCell align="center">Medication Plans</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.patients.map(row => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{row.id}
</TableCell>
<TableCell align="right">{row.name}</TableCell>
<TableCell align="right">{row.birthDate}</TableCell>
<TableCell align="right">{row.gender}</TableCell>
<TableCell align="right">{row.address}</TableCell>
<TableCell align="right">{row.medicalRecord}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
}
const style ={
display: 'flex',
justifyContent: 'center'
}
export default ListPatientComponent;
,并且有效。
我还添加了两个新的js文件ApiServicePatient.js和ApiServiceCaregiver.js:
import axios from 'axios';
const CAREGIVER_API_BASE_URL = 'http://localhost:8080/caregivers';
class ApiServiceCaregiver {
fetchCaregivers() {
return axios.get(CAREGIVER_API_BASE_URL);
}
fetchCaregiverById(caregiverId) {
return axios.get(CAREGIVER_API_BASE_URL + '/' + caregiverId);
}
deleteCaregiver(caregiverId) {
return axios.delete(CAREGIVER_API_BASE_URL + '/' + caregiverId);
}
addCaregiver(caregiver) {
return axios.post(""+CAREGIVER_API_BASE_URL, caregiver);
}
editCaregiver(caregiver) {
return axios.put(CAREGIVER_API_BASE_URL + '/' + caregiver.id, caregiver);
}
}
export default new ApiServiceCaregiver();
import axios from 'axios';
const PATIENT_API_BASE_URL = 'http://localhost:8080/patients';
class ApiServicePatient {
fetchPatients() {
return axios.get(PATIENT_API_BASE_URL);
}
fetchPatientById(userId) {
return axios.get(PATIENT_API_BASE_URL + '/' + userId);
}
deletePatient(userId) {
return axios.delete(PATIENT_API_BASE_URL + '/' + userId);
}
addPatient(user) {
return axios.post(""+PATIENT_API_BASE_URL, user);
}
editPatient(user) {
return axios.put(PATIENT_API_BASE_URL + '/' + user.id, user);
}
}
export default new ApiServicePatient();
此外,在App.js中,我添加了:
import React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import ListUserComponent from "./component/user/ListUserComponent";
import AddUserComponent from "./component/user/AddUserComponent";
import EditUserComponent from "./component/user/EditUserComponent";
import ListPatientComponent from "./component/patient/ListPatientComponent";
import ListCaregiverComponent from "./component/caregiver/ListCaregiverComponent";
function App() {
return (
<div className="container">
<Router>
<div className="col-md-6">
<h1 className="text-center" style={style}>React User Application</h1>
<Switch>
<Route path="/" exact component={ListUserComponent} />
<Route path="/users" component={ListUserComponent} />
<Route path="/add-user" component={AddUserComponent} />
<Route path="/edit-user" component={EditUserComponent} />
<Route path="/patients" component={ListPatientComponent} />
<Route path="/caregivers" component={ListCaregiverComponent} />
</Switch>
</div>
</Router>
</div>
);
}
const style = {
color: 'red',
margin: '10px'
}
export default App;
它不起作用,只会显示:
Unhandled Rejection (TypeError): Cannot read property 'map' of undefined
并以:
指示行<TableCell align="right">{row.address}</TableCell>
{row.patients.map(row => (
在后端应用程序中,类Caregiver
具有一个患者对象列表,映射为一对多:
@OneToMany(mappedBy = "caregiver", fetch = FetchType.EAGER)
private List<Patient> patients;
有人有建议吗?
--------在第一个答案后更新---------
我不再遇到该错误,但是我无法在护理人员表中显示分配的患者。对于每个护理人员的患者,对应的TableCell均为空。为什么会这样?
答案 0 :(得分:2)
您先做this.state.caregivers.map(row =>
,然后再做{row.patients.map(row =>
,但我看不到任何迹象表明每个caregivers
元素都有一个patients
数组属性
答案 1 :(得分:1)
由于您正在使用异步调用,因此javascript开始渲染,并且在短短的几毫秒之内,“ this.state.caregivers”没有任何值,因此您无法映射空值,因此它必须为空数组。
确保添加条件以首先检查或在构造函数中将“ this.state.caregivers”声明为空数组。
答案 2 :(得分:0)
尝试在每张地图之前添加要映射的属性,并&&
这样
this.state.caregivers && this.state.caregivers.map
对代码中的每个地图执行此操作。
希望这会有所帮助
答案 3 :(得分:0)
如其他答案所述,对于某些行,patients
可能是未定义的,因此您可以使用default value为它分配一个Destructuring:
{this.state.caregivers.map(({ id, name, birthDate, gender, address, patients = [] }) => (
<TableCell component="th" scope="row">
{id}
</TableCell>
<TableCell align="right">{name}</TableCell>
<TableCell align="right">{birthDate}</TableCell>
<TableCell align="right">{gender}</TableCell>
<TableCell align="right">{address}</TableCell>
{patients.map(row => (
...