Reputation: 80
I'm curious if the parameters(props) of a component can be de-structured similarly to an import if I want all the props but also to de-structure a single property. I guess this is more of a JavaScript question than a React question, but for example.
import React, {useEffect} from 'React'
I understand that an import is different than what I'm asking but I'm just using as an example. Is something like the following possible?
const props = {
test: true,
destructure: 'yes'
}
const TestComponent = (props, {desctructure}) => {
return <div>Not Important, but not having a return bothered me enough to add it</div>;
I'm well aware that I can do this:
const TestComponent = (props) => {
const { destructure } = props;
return <div>Another return</div>;
My reasoning for why this would be useful:
When navigating through large and overly complex components, I feel like the first option would make reading props much easier as it would stick out that these values are coming from props. Of course, a prop value could be written as props.destructure, but this almost feels like too much boilerplate if there's a lot of references.
I've been wondering this for a long time now and I really just want to make sure I'm not missing something simple here. I'm perfectly fine for doing the latter and I'm not looking for some custom implementation on this.
Upvotes: 2
Views: 6484
Reputation: 15
Sure. It's actually very straightforward to achieve this using ...rest
object. In your case I called it props
.
const Comp = ({ prop1, ...props }) => {
console.log(prop1); // cat
console.log(props.prop2); // dog
return null;
};
export default function App() {
return (
<div>
<Comp prop1="cat" prop2="dog" prop3="cow" />
</div>
);
}
Just be aware that your props object will no longer include destructured prop1.
Upvotes: 1
Reputation: 11027
The import example is a very different case. Exports are separated into the default and named exports, which can be done side by side.
What you could do, since you want to keep most of your props in the props object, but use some outside of it, is to use an object rest operator to spread the rest of the props into one object (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax):
const TestComponent = ({destructure, ...props}) => {
return <div>Another return</div>;
}
const TestComponent = ({destructure, ...props}) => {
console.log(destructure,props);
return <div>Another return
<br/>
destructure: {JSON.stringify(destructure)}
<br/>
props: {JSON.stringify(props)}
</div>;
}
ReactDOM.render(<TestComponent test destructure="yes" />,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Upvotes: 9
Reputation: 370679
There's very a hacky way, by using a default argument:
const props = {
test: true,
destructure: 'yes'
}
const App = (props, _, {destructure} = props) => {
console.log(props);
console.log(destructure);
return 'app';
};
ReactDOM.render(<App {...props} />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class="react"></div>
But it's very confusing. I wouldn't recommend it. Better to destructure on the first line if needed.
Note that from the code in your question:
import React, {useEffect} from 'React'
While this looks similar to destructuring, it's something entirely different. This is import syntax. Using a plain name when importing indicates to import the default export from the other module:
import React
Using brackets indicates to import the named export from the module:
import {useEffect}
It's not destructuring.
Upvotes: 0