Here's my "database" that I'm using,
index.js:
const workoutPlan = {
ID: 1,
Name: "My Workout Plan",
workout: {
day: "Monday",
exercises: [
{
Name: "Bench Press",
sets: [
{
set: 1,
weight: 135,
rep: 10
},
{
set: 2,
weight: 145,
rep: 8
}
]
},
{
Name: "Deadlift",
sets: [
{
set: 1,
weight: 135,
rep: 10
},
{
set: 2,
weight: 145,
rep: 8
}
]
}
]
}
};
Which then in my WorkoutPlan.js file, I'm passing the properties of the workoutPlan to my Workout.js child.
WorkoutPlan.js:
import React from "react";
import Workout from "./Workout";
import axios from "axios";
class WorkoutPlan extends React.Component {
constructor() {
super();
this.state = {
workoutPlan: {}
};
}
componentDidMount() {
axios
.get("/api/workout-plan")
.then(response => {
this.setState({ workoutPlan: response.data });
})
.catch(error => {
console.log(error);
});
}
render() {
const { workoutPlan } = this.state;
// const workoutPlan = this.state.workoutPlan;
return (
<div>
<h1>{workoutPlan.Name}</h1>
<Workout workout={workoutPlan.workout} />
</div>
);
}
}
export default WorkoutPlan;
In my Workout.js file, I'm trying to only map the exercises property of WorkoutPlan.workout.exercises. However, when I run this code, I'm running into a TypeError: Cannot read property 'exercises' of undefined
What am I doing wrong in this Child?
Workout.js:
import React from "react";
import Exercise from "./Exercise";
// const Workout = props => {
// props.workout.exercises.map(exercises => {
// return (
// <div>
// <h2>"Workout for {props.day}"</h2>
// <Exercise exercises={exercises} />
// </div>
// );
// });
// };
function Workout(props) {
props.workout.exercises.map(exercises => {
return (
<div>
<h2>"Workout for {props.day}"</h2>
<p>{exercises.Name}</p>
<Exercise exercises={exercises} />
</div>
);
});
}
export default Workout;
I've commented out the const, as I'm told that they're both methods are interchangeable. But if someone could actually provide some insight on how to do it on both methods, I'd be so grateful. The error is specifically referring to
props.workout.exercises.map(exercises => {
in my Workout.JS file
On the first render, the props.workout
value passed to the Workout
is undefined
because looking in the parent component WorkoutPlan
the default value for this.state.workoutPlan
is {}
so calling workoutPlan.workout
will be `undefined.
There are two approaches, in the parent don't render this component if the value is undefined
. Or, in the child, handle the value of undefined
.
Handling in the parent:
render() {
const { workout } = this.state.workoutPlan;
return (
<div>
<h1>{workoutPlan.Name}</h1>
{workout && <Workout workout={workout} />}
</div>
)
}
Or, in the child:
function Workout(props) {
// Early return if falsy value is passed (eg: undefined, null)
if (!props.workout) return null;
return props.workout.exercises.map(exercises => {
return (
<div>
<h2>"Workout for {props.day}"</h2>
<p>{exercises.Name}</p>
<Exercise exercises={exercises} />
</div>
);
});
}
Note, you also need to return
the props.workout.exercises.map
value.
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.