'How can I destructure a React prop and still access other props?

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.



Solution 1:[1]

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.

Solution 2:[2]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 daremes
Solution 2 CertainPerformance