Reputation: 13
I'm newer to React.js and JavaScript syntax, but didn't find a question answering the syntax I'm confused by in the below, so here it goes!
When using an array in React.js, why do I need to use additional dot notation on the passed prop to call a property within an array?
For example, In the Content
component, why do I have to type part.parts[0].name
in the below when in Java/C# I could just type parts[0].name
? If I don't do the above, I get a "parts[0].name is undefined" error.
The below code is from an exercise, so the intent is for me to sort through the weird logic and fix bugs as an exercise in correcting bad code. It's not pretty, but my solution below runs OK and there is more code that I'm not including, and I'm wondering why I have to use the additional dot notation... any explanation appreciated!
Let me know if my logic is wrong (and the structure of the code is terrible, I know), but if I'm passing the 'course.parts
' array directly to the Content
component, shouldn't JavaScript be able to grab the name
and exercises
properties when I pass the individual part
to the Part
component?
const App = () => {
const course = {
name: 'Half Stack application development',
parts: [
{
number: '1'
name: 'Fundamentals of React',
exercises: 10
},
{
number: '2'
name: 'Using props to pass data',
exercises: 7
},
{
number: '3'
name: 'State of a component',
exercises: 14
}
]
}
return (
<div>
<Header course={course.name} />
<Content parts={course.parts} />
<Total parts={course.parts} />
</div>
)
}
const Part = (part) => {
return (
<>
<h2>Part {part.number}: {part.name}</h2>
<h3>{part.exercises} exercises</h3>
</>
)
}
const Content = (parts) => {
console.log(parts[0])
return (
<>
<Part part={parts[0]} name={parts.parts[0].name} exercises={parts.parts[0].exercises} number={parts.parts[0].number} />
</>
)
}
Upvotes: 0
Views: 671
Reputation: 44
All the passed data are stored in a props object. You have to access the passed key like parts in your case through props object. You can use destructuring like const Part = ({ parts }) =>. Take some time and read the documentation.
Upvotes: 0
Reputation: 476
<Content parts={course.parts} />
Basically in React, this line means a function that has parameter object like function(params)
and in that line, it will be like Content({ parts: course.parts })
so your code const Content = (parts) => {...}
is the function that accept that params.
To make it more understandable. you can rename the parts
in the bracket to be params
or usually props
in React.
so props
is an object.. you can do something like this instead..
const Content = ({ parts }) => {...}
which means destructing (ES6 way) the object to the parts. then you can use it directly parts[0].name
Sorry for the weird explanation.
Upvotes: 0
Reputation: 1074505
The first argument passed to a component function is an object with properties for each of the component's props. So if you call:
<Content parts={x} />
...the Content
function is called with an object with a parts
property on it. That's so if there are other properties, they can be passed all together.
It's fairly common with react function components to use object destructuring to pick out the desired props, like this:
const Content = ({parts}) => {
// ^−−−−−^−−−−−−−−−−−−−−−− object destructuring
return (
<>
<Part part={parts[0]} name={parts[0].name} exercises={parts[0].exercises} number={parts[0].number} />
</>
);
};
That's functionally equivalent to:
const Content = (props) => {
const parts = props.parts;
return (
<>
<Part part={parts[0]} name={parts[0].name} exercises={parts[0].exercises} number={parts[0].number} />
</>
);
};
Side note: There's no need to use a fragment when you're returning just one element:
const Content = ({parts}) => {
return <Part part={parts[0]} name={parts[0].name} exercises={parts[0].exercises} number={parts[0].number} />;
};
or
const Content = ({parts}) => {
return <Part
part={parts[0]}
name={parts[0].name}
exercises={parts[0].exercises}
number={parts[0].number}
/>;
};
And if you're already passing the part, then it seems unnecessary to pass name
, exercises
, and number
separately; Part
should be able to get them from the object it receives as its part
property. WHich would give us:
const Content = ({parts}) => {
return <Part part={parts[0]} />;
};
Upvotes: 1