我有一个令人难以置信的问题,其中所有这三个<RecordAdmin>
组件实例似乎都使用页面加载时首先加载哪个组件的状态。
我不知道它是如何发生的,或者为什么,并且奇怪的是,它以前是起作用的。
<Switch>
<Route path="/admin/books">
<RecordAdmin singular="book" plural="books" table={BookTable} form={BookForm} />
</Route>
<Route path="/admin/authors">
<RecordAdmin singular="author" plural="authors" table={AuthorTable} form={AuthorForm} />
</Route>
<Route path="/admin/branches">
<RecordAdmin singular="branch" plural="branches" table={BranchTable} form={BranchForm} />
</Route>
</Switch>
使用console.log
,似乎所有这三个组件将具有相同的this.state.records
对象。每个组件实例都不应该有自己的状态吗?
这里是<RecordAdmin>
组件的来源:
import React from "react";
import Axios from "axios";
import {
Switch,
Route,
NavLink,
Redirect
} from "react-router-dom";
class NewRecordForm extends React.Component {
constructor(props) {
super(props);
this.state = {
redirect: false,
};
}
handleSubmit = (event, formFields, multipart = false) => {
event.preventDefault();
let formData = null;
let config = null;
if (multipart) {
formData = new FormData();
for (let [key, value] of Object.entries(formFields)) {
formData.append(key, value)
}
config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
} else {
formData = formFields;
}
Axios.post(`${process.env.REACT_APP_API_URL}/${this.props.plural}`, formData, config)
.then(response => {
this.setState({redirect: true})
}).catch(error => {
console.log(error)
})
}
render() {
if (this.state.redirect) {
this.props.redirectCallback();
}
const Form = this.props.form
return (
<div>
{this.state.redirect ? <Redirect to={`/admin/${this.props.plural}`} /> : null}
<Form handleSubmit={this.handleSubmit} />
</div>
)
}
}
function errorMessage(props) {
return (
<div class="alert alert-danger" role="alert">
{props.msg}
</div>
)
}
export default class RecordAdmin extends React.Component {
constructor(props) {
super(props)
this.state = {
records: []
}
}
componentDidMount() {
this.loadRecords();
}
loadRecords = () => {
Axios.get(process.env.REACT_APP_API_URL + '/' + this.props.plural)
.then(response => {
this.setState({records: response.data})
}).catch(error => {
console.log(error)
})
}
deleteRecord = (event, recordId) => {
event.preventDefault();
Axios.delete(process.env.REACT_APP_API_URL + '/' + this.props.plural + '/' + recordId).then(response => {
this.loadRecords();
})
}
render() {
// this allows us to pass props to children that are loaded via {this.props.children}
// more on that here: https://medium.com/better-programming/passing-data-to-props-children-in-react-5399baea0356
const TableComponent = this.props.table
return (
<div className="admin-body">
{this.state.errorMessage ? <errorMessage msg={this.state.errorMessage} /> : null}
<Switch>
<Route exact path={`/admin/${this.props.plural}`}>
<div className="admin-menu">
<NavLink className="btn btn-primary" to={`/admin/${this.props.plural}/new`}>New {this.props.singular.charAt(0).toUpperCase() + this.props.singular.slice(1)}</NavLink>
</div>
<TableComponent records={this.state.records} deleteRecord={this.deleteRecord} />
</Route>
<Route exact path={`/admin/${this.props.plural}/new`}>
<NewRecordForm plural={this.props.plural} form={this.props.form} redirectCallback={this.loadRecords}/>
</Route>
</Switch>
</div>
);
}
}
编辑:
[当我抛出console.log
时,我看到无论页面当前选择了哪个<RecordAdmin>
实例,页面加载时加载的第一个<RecordAdmin>
都将其记录输出到控制台。
render() {
// this allows us to pass props to children that are loaded via {this.props.children}
// more on that here: https://medium.com/better-programming/passing-data-to-props-children-in-react-5399baea0356
const TableComponent = this.props.table
console.log(this.records) // No matter which <RecordAdmin> is currently being displayed, the records will be the records from whichever <RecordComponent was first loaded on page load.
return (
<div className="admin-body">
{this.state.errorMessage ? <errorMessage msg={this.state.errorMessage} /> : null}
<Switch>
<Route exact path={`/admin/${this.props.plural}`}>
<div className="admin-menu">
<NavLink className="btn btn-primary" to={`/admin/${this.props.plural}/new`}>New {this.props.singular.charAt(0).toUpperCase() + this.props.singular.slice(1)}</NavLink>
</div>
{console.log(this.state.records)}
<TableComponent records={this.state.records} deleteRecord={this.deleteRecord} />
</Route>
<Route exact path={`/admin/${this.props.plural}/new`}>
<NewRecordForm plural={this.props.plural} form={this.props.form} redirectCallback={this.loadRecords}/>
</Route>
</Switch>
</div>
);
}
无论正在显示哪个<RecordAdmin>
实例,使用console.log
都表明状态正在所有3个<RecordAdmin>
实例之间共享。
您可以为key
的每个实例使用不同的RecordAdmin
,也许只是为了确保可以传递exact={true}
。