Я пытаюсь создать веб-приложение, используя React
, Redux
и Django REST framework
. API предоставляет два разных типа пользователей. Одной из них является модель с именем Counselor
, владельцем которой является auth.User
, как показано в коде ниже:
class Counselor(models.Model):
owner = models.ForeignKey('auth.User',
related_name='counselors',
on_delete=models.CASCADE)
# other fields...
Класс Counselor
будет хранить идентификатор владельца, а API предоставляет конечную точку для получить владельца по его идентификатору, то есть r'^users/(?P<pk>[0-9]+)/$'
и другой конечной точке, чтобы получить все объекты Counselor
в коллекции.
Используя react-redux
, я создал компонент, который будет вызывать действие для получения всех Counselor
объекты и еще один объект для извлечения владельца по идентификатору владельца (консультанта).
Я хотел бы отобразить только 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
, поэтому я могу получить идентификатор. Однако, когда вызывается 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);
Не могли бы вы посоветовать? Спасибо!