Reputation: 31365
I'm currently building an AddProductPage
component for my web app. It receives a bunch of props
from its parent AddProductContainer
and should divide those props
among many smaller components that it renders on the page.
Example:
AddProductPage.js
function AddProductPage(props) {
return(
<React.Fragment>
<Component1
propsA={props.propsA}
propsB={props.propsB}
/>
<Component2
propsC={props.propsC}
propsD={props.propsD}
propsE={props.propsE}
/>
// And so on...
</React.Fragment>
);
}
I've decided that I will to divide the full props
object into smaller objects, one for each component, so I can see what my code will render on the page in a cleaner look. Like:
function AddProductPage(props) {
const comp1Props = {
propsA: props.propsA,
propsB: props.propsB
}
const comp2Props = {
propsC: props.propsC,
propsD: props.propsD,
propsE: props.propsE
}
return(
<React.Fragment>
<Component1 {...comp1Props}/> // <--- Easier to see what will render
<Component2 {...comp2Porps}/>
// And so on...
</React.Fragment>
);
}
I'm currently thinking if is it possible to dynamically destructure (or some other approach) all props
into single variables so I can write something like this:
function AddProductPage(props) {
// Some code to destructure all props into single variables
const comp1Props = {
propsA,
propsB
};
const comp2Props = {
propsC,
propsD,
propsE
};
return(
<React.Fragment>
<Component1 {...comp1Props}/> // <--- Easier to see what will render
<Component2 {...comp2Porps}/>
// And so on...
</React.Fragment>
);
}
How can I do this?
EDIT
I think I wasn't being clear enough with my question. But what I meant with dynamically is to destructure everything without knowing the props
names or how many props
there are. Is it possible?
Like:
const {...props} = {...props}; // This is pseudo code
This way I think my code will be as clean as it can get. Thanks.
Upvotes: 1
Views: 8821
Reputation: 12964
You can use:
function AddProductPage({propsA, propsB, propsC, propsD, propsE}) {
Or
const {propsA, propsB, propsC, propsD, propsE} = props
Upvotes: 0
Reputation: 700
I am a bit late to the party, but I would like to make a mention how to make your code readable and thus maintainable. You should separate you code and thus separate your concerns.
Personally I think you are thinking overkill for what you need. For every Component1
, Component2
, Component3
etc. You will be declaring another const
value, which depending on how many you have will have a performance impact. More importantly, Have you Component and the props being passed in laid out like below (not inline with the component) makes it a lot cleaner.
class MyComponentName extends Component {
getComponentOne = () => {
const { propsA, propsB } = this.props;
//Any other logic for component 1 can go here.
return (
<Component1
propsA={propsA}
propsB={propsB}
/>
);
};
getComponentTwo = () => {
const { propsC, propsD, propsE} = this.props;
//Any other logic for component 2 can go here.
return (
<Component2
propsC={propsC}
propsD={propsD}
propsE={propsE}
/>
);
};
// Other component method getters
addProductPage = () => (
<React.Fragment>
{this.getComponentOne()}
{this.getComponentTwo()}
// Get other component methods
</React.Fragment>
);
render() {
return(
// Return whatever you wish here.
);
}
}
export default MyComponentName;
Two great quotes to think about are from C. Martin in which he stated in his book Clean Code: A Handbook of Agile Software Craftsmanship:
Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.
AND
“Clean code is code that has been taken care of. Someone has taken the time to keep it simple and orderly. They have paid appropriate attention to details. They have cared.”
Also A note regarding my example above, I am using class components, as I don't know if your component has any other methods/ logic. As if you have other methods in your functional component, on each render those methods would get reinitiated, which again would be a big performance issue.
If you just have a functional component and don't want to separate your code/ has no logic and it only return JSX
then you could do it the following way.
const MyComponentName = ({
propA,
propB,
propC,
propD,
propE,
// Rest of props
}) => (
<React.Fragment>
<Component1
propsA={propsA}
propsB={propsB}
/>
<Component2
propsC={propsC}
propsD={propsD}
propsE={propsE}
/>
// Rest of you components (If simply returning JSX)
</React.Fragment>
);
Hope the above is of some help to you.
Upvotes: 2
Reputation: 1074335
The "Some code to destructure all props into single variables" would be simple destructuring:
const { propsA, propsB, propsC, propsD, propsE } = props;
Live Example:
const props = {
propsA: "a",
propsB: "b",
propsC: "c",
propsD: "d",
propsE: "e"
};
const { propsA, propsB, propsC, propsD, propsE } = props;
const comp1Props = {
propsA,
propsB
};
const comp2Props = {
propsC,
propsD,
propsE
};
console.log(comp1Props);
console.log(comp2Props);
.as-console-wrapper {
max-height: 100% !important;
}
In comments you've clarified:
what I meant with dynamically is to destructure everything without knowing the props names or how many props there are.
I asked how you would know what to assign to comp1Props
vs comp2Props
, and you said:
I woud still decide that and create those objects manually. But if a pass a new prop to
AddProductPage
, I would like it to be automatically destructured and available to add that into the comp1Props object, for example. Otherwise I would have to remember to destructure it first and then add it to thecomp1Props
object.
So the question is: Can you automatically create constants/variables for all of props
's properties in AddProductPage
, so that they're all available to use in the code creating comp1Props
and comp2Props
?
No, you can't do that without using a confusing feature (with
) that isn't available in strict mode (which is enabled by default in modules). If you could use with
, you'd just do with (props) { /*...*/ }
and create your comp1Props
and comp2Props
within that block. But you can't use with
in modern JavaScript.
You're probably best off doing what you're already doing:
const comp1Props = {
propsA: props.propsA,
propsB: props.propsB
};
But if you want to make it shorter, you can give yourself a reusable utility function:
function pick(source, ...props) {
const result = {};
for (const prop of props) {
result[prop] = source[prop];
}
}
and then use it in AddProductPage
:
function AddProductPage(props) {
const comp1Props = pick(props, "propsA", "propsB");
const comp2Props = pick(props, "propsC", "propsD", "propsE");
return(
<React.Fragment>
<Component1 {...comp1Props}/>
<Component2 {...comp2Porps}/>
// And so on...
</React.Fragment>
);
}
(Some would shoehorn that into a reduce
call, but there's no need.)
Upvotes: 7
Reputation: 4330
you can do something like
function AddProductPage(props) {
//Destructuring props and storing each keys in a sep varaiable
const { propsA, propsB, propsC, propsD, propsE } = props;
const comp1Props = {
propsA,
propsB
};
const comp2Props = {
propsC,
propsD,
propsE
};
return(
<React.Fragment>
<Component1 {...comp1Props}/>
<Component2 {...comp2Porps}/>
// And so on...
</React.Fragment>
);
}
Upvotes: 2