从 React Hooks GET 映射出 DOM 个节点
Mapping out DOM nodes from React Hooks GET
提前为我的问题措辞不当而道歉。
我遵循了 MERN 教程,该教程全部使用基于 class 的 React 组件完成。我正在尝试将其转换为带钩子的功能组件。
我无法从初始 GET 请求中保存 users/usernames,然后将它们映射到 html select 表单,以便可以归因于新表单提交给现有用户之一。
教程代码如下所示,可以按预期运行:
import React, { Component } from 'react';
import axios from 'axios';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
export default class CreateRide extends Component {
constructor(props) {
super(props);
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangeDescription = this.onChangeDescription.bind(this);
this.onChangeDuration = this.onChangeDuration.bind(this);
this.onChangeDistance = this.onChangeDistance.bind(this);
this.onChangeDate = this.onChangeDate.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username: '',
description: '',
duration: 0,
distance: 0,
date: new Date(),
users: []
}
}
componentDidMount() {
axios.get('http://localhost:5000/users/')
.then(response => {
if (response.data.length > 0) {
this.setState({
users: response.data.map(user => user.username),
username: response.data[0].username
});
}
})
.catch((error) => {
console.log(error);
})
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeDescription(e) {
this.setState({
description: e.target.value
});
}
onChangeDuration(e) {
this.setState({
duration: e.target.value
});
}
onChangeDistance(e) {
this.setState({
distance: e.target.value
});
}
onChangeDate(date) {
this.setState({
date: date
});
}
onSubmit(e) {
e.preventDefault();
const ride = {
username: this.state.username,
description: this.state.description,
duration: this.state.duration,
distance: this.state.distance,
date: this.state.date
};
console.log(ride);
axios.post('http://localhost:5000/rides/add', ride)
.then(res => console.log(res.data));
window.location = '/';
}
render() {
return (
<div>
<h3>Create New Ride Log</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username: </label>
<select ref="userInput"
required
className="form-control"
value={this.state.username}
onChange={this.onChangeUsername}>
{
this.state.users.map(function (user) {
return <option
key={user}
value={user}>{user}
</option>;
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text"
required
className="form-control"
value={this.state.description}
onChange={this.onChangeDescription}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="text"
className="form-control"
value={this.state.duration}
onChange={this.onChangeDuration}
/>
</div>
<div className="form-group">
<label>Distance (in miles): </label>
<input
type="text"
className="form-control"
value={this.state.distance}
onChange={this.onChangeDistance}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
selected={this.state.date}
onChange={this.onChangeDate}
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Create Ride Log" className="btn btn-primary" />
</div>
</form>
</div>
)
}
}
我的目标代码在 ComponentDidMount() {...} 中,将用户和用户名映射到状态,然后在下面的 html 渲染中再次出现。
我现在拥有的功能组件如下所示:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
const CreateRide = (props) => {
const [username, setUsername] = useState('');
const [description, setDescription] = useState('');
const [duration, setDuration] = useState(0);
const [distance, setDistance] = useState(0);
const [date, setDate] = useState(new Date());
const [users, setUsers] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await axios.get('http://localhost:5000/users/');
if (response.data.length > 0) {
setUsers({ users: response.data.map(user => user.username ) });
setUsername({ username: response.data[0].username });
}
}
fetchData();
}, []);
const onChangeUsername = (e) => {
setUsername(e.target.value);
}
const onChangeDescription = (e) => {
setDescription(e.target.value);
}
const onChangeDuration = (e) => {
setDuration(e.target.value);
}
const onChangeDistance = (e) => {
setDistance(e.target.value);
}
const onChangeDate = (date) => {
setDate(date);
}
const onSubmit = (e) => {
e.preventDefault();
const ride = {
username: username,
description: description,
duration: duration,
distance: distance,
date: date
};
console.log(ride);
axios.post('http://localhost:5000/rides/add', ride)
.then(res => console.log(res.data));
window.location = '/';
}
return (
<div>
<h3>Create New Ride Log</h3>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Username: </label>
<select
required
className="form-control"
value={username}
onChange={onChangeUsername}>
{
users.map(user => {
return <option key={user} value={user}>{user}</option>;
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text"
required
className="form-control"
value={description}
onChange={onChangeDescription}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="text"
className="form-control"
value={duration}
onChange={onChangeDuration}
/>
</div>
<div className="form-group">
<label>Distance (in miles): </label>
<input
type="text"
className="form-control"
value={distance}
onChange={onChangeDistance}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
selected={date}
onChange={onChangeDate}
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Create Ride Log" className="btn btn-primary" />
</div>
</form>
</div>
)
}
export default CreateRide;
这是我通过邮递员 运行 回复的示例 json 的样子:
[
{
"_id": "5f39e38abfa99e273e299fd8",
"username": "Rudy",
"createdAt": "2020-08-17T01:55:22.797Z",
"updatedAt": "2020-08-17T01:55:22.797Z",
"__v": 0
},
{
"_id": "5f39e391bfa99e273e299fd9",
"username": "James",
"createdAt": "2020-08-17T01:55:29.727Z",
"updatedAt": "2020-08-17T01:55:29.727Z",
"__v": 0
},
{...}
]
进一步往下 HTML,我正在努力概念化如何在第一个表单组中使用 ref='userInput'。使用功能组件会产生不允许字符串引用的错误。
我知道这包含不止一个问题,但我很忙,如果有任何问题,我们将不胜感激。
按顺序回答您的问题:
1.用户数据: 您正在对象中设置用户数据:
setUsers({ users: response.data.map(user => user.username ) });
setUsername({ username: response.data[0].username });
应该是:
setUsers(response.data.map(user => user.username));
setUsername(response.data[0].username);
2。 Refs: 您似乎没有在原始 class-based 代码中使用该 ref,您应该可以将其删除。如果你确实需要引用 select
元素,你可以使用 useRef
钩子,文档在这里:https://reactjs.org/docs/hooks-reference.html#useref
提前为我的问题措辞不当而道歉。
我遵循了 MERN 教程,该教程全部使用基于 class 的 React 组件完成。我正在尝试将其转换为带钩子的功能组件。
我无法从初始 GET 请求中保存 users/usernames,然后将它们映射到 html select 表单,以便可以归因于新表单提交给现有用户之一。
教程代码如下所示,可以按预期运行:
import React, { Component } from 'react';
import axios from 'axios';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
export default class CreateRide extends Component {
constructor(props) {
super(props);
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangeDescription = this.onChangeDescription.bind(this);
this.onChangeDuration = this.onChangeDuration.bind(this);
this.onChangeDistance = this.onChangeDistance.bind(this);
this.onChangeDate = this.onChangeDate.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username: '',
description: '',
duration: 0,
distance: 0,
date: new Date(),
users: []
}
}
componentDidMount() {
axios.get('http://localhost:5000/users/')
.then(response => {
if (response.data.length > 0) {
this.setState({
users: response.data.map(user => user.username),
username: response.data[0].username
});
}
})
.catch((error) => {
console.log(error);
})
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeDescription(e) {
this.setState({
description: e.target.value
});
}
onChangeDuration(e) {
this.setState({
duration: e.target.value
});
}
onChangeDistance(e) {
this.setState({
distance: e.target.value
});
}
onChangeDate(date) {
this.setState({
date: date
});
}
onSubmit(e) {
e.preventDefault();
const ride = {
username: this.state.username,
description: this.state.description,
duration: this.state.duration,
distance: this.state.distance,
date: this.state.date
};
console.log(ride);
axios.post('http://localhost:5000/rides/add', ride)
.then(res => console.log(res.data));
window.location = '/';
}
render() {
return (
<div>
<h3>Create New Ride Log</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username: </label>
<select ref="userInput"
required
className="form-control"
value={this.state.username}
onChange={this.onChangeUsername}>
{
this.state.users.map(function (user) {
return <option
key={user}
value={user}>{user}
</option>;
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text"
required
className="form-control"
value={this.state.description}
onChange={this.onChangeDescription}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="text"
className="form-control"
value={this.state.duration}
onChange={this.onChangeDuration}
/>
</div>
<div className="form-group">
<label>Distance (in miles): </label>
<input
type="text"
className="form-control"
value={this.state.distance}
onChange={this.onChangeDistance}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
selected={this.state.date}
onChange={this.onChangeDate}
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Create Ride Log" className="btn btn-primary" />
</div>
</form>
</div>
)
}
}
我的目标代码在 ComponentDidMount() {...} 中,将用户和用户名映射到状态,然后在下面的 html 渲染中再次出现。
我现在拥有的功能组件如下所示:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
const CreateRide = (props) => {
const [username, setUsername] = useState('');
const [description, setDescription] = useState('');
const [duration, setDuration] = useState(0);
const [distance, setDistance] = useState(0);
const [date, setDate] = useState(new Date());
const [users, setUsers] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await axios.get('http://localhost:5000/users/');
if (response.data.length > 0) {
setUsers({ users: response.data.map(user => user.username ) });
setUsername({ username: response.data[0].username });
}
}
fetchData();
}, []);
const onChangeUsername = (e) => {
setUsername(e.target.value);
}
const onChangeDescription = (e) => {
setDescription(e.target.value);
}
const onChangeDuration = (e) => {
setDuration(e.target.value);
}
const onChangeDistance = (e) => {
setDistance(e.target.value);
}
const onChangeDate = (date) => {
setDate(date);
}
const onSubmit = (e) => {
e.preventDefault();
const ride = {
username: username,
description: description,
duration: duration,
distance: distance,
date: date
};
console.log(ride);
axios.post('http://localhost:5000/rides/add', ride)
.then(res => console.log(res.data));
window.location = '/';
}
return (
<div>
<h3>Create New Ride Log</h3>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Username: </label>
<select
required
className="form-control"
value={username}
onChange={onChangeUsername}>
{
users.map(user => {
return <option key={user} value={user}>{user}</option>;
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text"
required
className="form-control"
value={description}
onChange={onChangeDescription}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="text"
className="form-control"
value={duration}
onChange={onChangeDuration}
/>
</div>
<div className="form-group">
<label>Distance (in miles): </label>
<input
type="text"
className="form-control"
value={distance}
onChange={onChangeDistance}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
selected={date}
onChange={onChangeDate}
/>
</div>
</div>
<div className="form-group">
<input type="submit" value="Create Ride Log" className="btn btn-primary" />
</div>
</form>
</div>
)
}
export default CreateRide;
这是我通过邮递员 运行 回复的示例 json 的样子:
[
{
"_id": "5f39e38abfa99e273e299fd8",
"username": "Rudy",
"createdAt": "2020-08-17T01:55:22.797Z",
"updatedAt": "2020-08-17T01:55:22.797Z",
"__v": 0
},
{
"_id": "5f39e391bfa99e273e299fd9",
"username": "James",
"createdAt": "2020-08-17T01:55:29.727Z",
"updatedAt": "2020-08-17T01:55:29.727Z",
"__v": 0
},
{...}
]
进一步往下 HTML,我正在努力概念化如何在第一个表单组中使用 ref='userInput'。使用功能组件会产生不允许字符串引用的错误。
我知道这包含不止一个问题,但我很忙,如果有任何问题,我们将不胜感激。
按顺序回答您的问题:
1.用户数据: 您正在对象中设置用户数据:
setUsers({ users: response.data.map(user => user.username ) });
setUsername({ username: response.data[0].username });
应该是:
setUsers(response.data.map(user => user.username));
setUsername(response.data[0].username);
2。 Refs: 您似乎没有在原始 class-based 代码中使用该 ref,您应该可以将其删除。如果你确实需要引用 select
元素,你可以使用 useRef
钩子,文档在这里:https://reactjs.org/docs/hooks-reference.html#useref