我正在尝试使用React
、Redux
和Django REST framework
构建一个web应用程序。API提供了两种不同类型的用户。其中一个是一个名为Counselor
的模型,其所有者为auth.User
,如下代码所示:
class Counselor(models.Model):
owner = models.ForeignKey('auth.User',
related_name='counselors',
on_delete=models.CASCADE)
# other fields...
Counselor
类将存储所有者id,API提供一个端点以通过其id检索所有者,即r'^users/(?P<pk>[0-9]+)/$'
和另一个端点来检索集合中的所有Counselor
对象。
使用react-redux
,我构建了一个组件,该组件将调用一个操作来检索所有Counselor
对象,另一个操作用于检索给定所有者id(顾问(的所有者。
我想在组件形式中只显示Counselor
的first_name
和last_name
。但是,操作返回undefined
。
下面的代码和我尝试做的事情:
用户减速器
import {
// ...
GET_USER,
} from "../actions/types";
const initialState = {
token: localStorage.getItem("token"),
isAuthenticated: false,
isLoading: false,
user: null,
};
export default function (state = initialState, action) {
switch (action.type) {
// ...
case USER_LOADED:
case GET_USER:
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.payload,
};
// ...
default:
return state;
}
}
用户操作
// GET User
export const getUser = (id) => (dispatch, getState) => {
axios
.get(`/api/users/${id}/`, tokenConfig(getState))
.then((res) => {
dispatch({
type: GET_USER,
payload: res.data,
});
})
.catch((err) => {
dispatch(returnErrors(err.response.data, err.response.status));
});
};
顾问减速器
import {
GET_COUNSELOR,
// ...
} from "../actions/types";
const initialState = {
isRegistering: false,
counselors: [],
};
export default function (state = initialState, action) {
switch (action.type) {
// ...
case GET_COUNSELOR:
return {
...state,
isRegistering: false,
counselors: action.payload,
};
// ...
default:
return state;
}
}
顾问行动
// GET Counselor
export const getCounselors = () => (dispatch, getState) => {
axios
.get("/api/counselors/", tokenConfig(getState))
.then((res) => {
dispatch({
type: GET_COUNSELOR,
payload: res.data,
});
})
.catch((err) =>
dispatch(returnErrors(err.response.data, err.response.status))
);
};
在React
组件中,我将调用动作getCounselors
和getUser
。调用getCounselors
时,会填充counselors
状态,因此我可以检索id。但是,调用getUser(counselor.id)
时,对象是undefined
。
以下部件代码:
表单组件(我调用带有注释的getUser的点(
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { getCounselors } from "../../actions/counselors";
import { getUser } from "../../actions/auth";
import { postAppointment } from "../../actions/appointments";
export class Form extends Component {
state = {
title: "",
date: "",
start_time: "",
end_time: "",
location: "",
description: "",
counselor: "",
};
static propTypes = {
counselors: PropTypes.array.isRequired,
postAppointment: PropTypes.func.isRequired,
getUser: PropTypes.func.isRequired,
};
componentDidMount() {
this.props.getCounselors();
}
onChange = (e) => this.setState({ [e.target.name]: e.target.value });
onSubmit = (e) => {
e.preventDefault();
const {
title,
date,
start_time,
end_time,
location,
description,
counselor,
} = this.state;
const appointment = {
title,
date,
start_time,
end_time,
location,
description,
counselor,
};
this.props.postAppointment(appointment);
this.setState({
title: "",
date: "",
start_time: "",
end_time: "",
location: "",
description: "",
counselor: "",
});
};
render() {
const {
title,
date,
start_time,
end_time,
location,
description,
counselor,
} = this.state;
return (
<div className="col-md-6 m-auto">
<div className="card card-body mt-4 mb-4">
<h2>Book an Appointment</h2>
<form onSubmit={this.onSubmit}>
{/* some divs ... */}
<div className="form-group">
<label>Counselor</label>
<select
type="text"
className="form-control"
name="counselor"
onChange={this.onChange}
value={counselor}
>
<option value="" disabled>
Choose...
</option>
{this.props.counselors.map((counselor) => (
<option key={counselor.id}>
{this.props.getUser(counselor.owner)} {/* HERE!!! */}
</option>
))}
</select>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Book
</button>
</div>
</form>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
counselors: state.counselors.counselors,
});
export default connect(mapStateToProps, {
getCounselors,
postAppointment,
getUser,
})(Form);
你能给我个建议吗?谢谢
据我所知,您没有从getUser
返回任何内容,这就是您获得undefined
的原因。您尝试同步获取异步数据的第二个问题是不正确的。也许你需要两样东西:
- 制作api端点以获取用户数组,而不是向服务器发出许多请求
- 在
componentDidUpdate
中提出此请求
事实上,我不知道你的应用程序的架构,但看起来有点奇怪,你从服务器上获得了一组顾问,然后从每个对象中获得id,并再次提出请求,但也许你真的需要它(无论如何,请注意这一点(