简体   繁体   中英

Cannot read property 'map' of undefined Error when using axios.get inside useEffect hook

This is my edit-exercises component given below. So in my exercises component when I am clicking edit to update my exercises with respect to its id, it has to render to edit-exercise component but on rendering it gives above mentioned error. This is my component for the reference. In this, in useEffect I am fetching my exercise with given id from the URL.

    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
   
 

Cannot read property 'map' of undefined

This error is thrown because the array you are trying to map doesn't exist. Please check if the array exists before you map the array. users: res.data? res.data.map((user) => user.username): [], And

{userDetails.users && userDetails.users.map((user) => {
        return (
            <option key={user} value={user}>
                {user}
            </option>
            );
         })}

Since axios.get returns a promise, and setUserDetails is set after the promise is returned, you need to be careful on when useEffect is triggered. Currently useEffect is triggered when props.match.params.id is changed.

There are 2 possible solutions for it: Either, you can remove props.match.params.id from the useEffect second parameter.

Or you can this section outside the useEffect hook:

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);
      });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM