在 useEffect 钩子中使用 axios.get 时无法读取未定义的属性“map”错误
2021-05-20
85
这是我的 edit-exercises 组件,如下所示。因此,在我的练习组件中,当我单击 edit 以根据其 id 更新我的练习时,它必须呈现到 edit-exercise 组件 但在呈现时,它会出现上述错误。这是我的组件,供参考。在此,在 useEffect 中,我从 URL 中获取具有给定 id 的练习。
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import axios from "axios";
const EditExercise = (props) => {
const [userDetails, setUserDetails] = useState({
username: "",
description: "",
duration: 0,
date: new Date(),
users: [],
});
useEffect(() => { //This is the getting from backend
axios
.get("http://localhost:5000/exercises/"+props.match.params.id)
.then(res => {
setUserDetails({
username: res.data.username,
description: res.data.description,
duration: res.data.duration,
date: new Date(res.data.date),
})
})
.catch((err) => {
console.log(err);
});
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});
},[props.match.params.id]);
const changeUsernameHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
username: e.target.value,
};
});
};
const changeDescriptionHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
description: e.target.value,
};
});
};
const changeDurationHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
duration: e.target.value,
};
});
};
const changeDateHandler = (date) => {
setUserDetails((prevState) => {
return {
...prevState,
date: date,
};
});
};
const onSubmitHandler = (e) => { //On submit this code will run
e.preventDefault();
const exercise = {
username: userDetails.username,
description: userDetails.description,
duration: userDetails.duration,
date: userDetails.date,
};
console.log(exercise);
axios
.post("http://localhost:5000/exercises/update/"+props.match.params.id, exercise)
.then((res) => console.log(res.data));
window.location = "/";
};
return (
<div>
<h3>Edit Exercise log</h3>
<form onSubmit={onSubmitHandler}>
<div className="form-group">
<label>Username: </label>
<select
required
className="form-control"
onChange={changeUsernameHandler}
value={userDetails.username}
>
{userDetails.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"
onChange={changeDescriptionHandler}
value={userDetails.description}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="number"
className="form-control"
onChange={changeDurationHandler}
value={userDetails.duration}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
onChange={changeDateHandler}
selected={userDetails.date}
/>
</div>
</div>
<div>
<input
type="submit"
value="Edit Exercise Log"
className="btn btn-primary"
/>
</div>
</form>
</div>
);
};
export default EditExercise;```
>Please suggest what can be done to render the edit-exercise component
1个回答
Cannot read property 'map' of undefined
抛出此错误是因为您尝试映射的数组不存在。请在映射数组之前检查该数组是否存在。 users: res.data ? res.data.map((user) => user.username) : [], 并且
{userDetails.users && userDetails.users.map((user) => {
return (
<option key={user} value={user}>
{user}
</option>
);
})}
由于
axios.get
返回一个承诺,而
setUserDetails
是在承诺返回后设置的,因此您需要注意何时触发
useEffect
。目前,当
props.match.params.id
发生更改时,会触发
useEffect
。
有两种可能的解决方案:
要么,您可以从
useEffect
第二个参数中删除
props.match.params.id
。
或者您可以在 useEffect 钩子之外使用此部分:
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});
Suraj Neupane
2021-05-20