开发者问题收集

在 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