Ilja
Ilja

Reputation: 46527

How to pass all other props to react class?

Say I have 3 props that my class based component requires and implements i.e.

<Component propOne={this.props.one} propTwo={this.props.two}>
  {this.props.children}
</Component>

how would I pass down any other props that I originally don't expect, but say someone else using my component would want to use?

I was thinking

<Component propOne={this.props.one} propTwo={this.props.two} {...this.props} >
  {this.props.children}
</Component>

But am concerned about prop duplication

Upvotes: 77

Views: 84541

Answers (5)

Amir M. Mohamadi
Amir M. Mohamadi

Reputation: 1522

Here is how I do it:

export default function Button(props) {
  const { children, label, ...rest } = props;
  
  return (
    <button
      {...rest}
      aria-label={label}
    >
      {children}
    </button>
  )
}

Just be aware sometimes you do not need attributes named the same as the given prop, so here I extracted label and passed it to aria-label.

Upvotes: 9

Kousha
Kousha

Reputation: 36289

Use spread syntax:

const {propOne, propTwo, ...leftOver} = this.props;
// `leftOver` contains everything except `propOne` and `propTwo`

So your example would become:

const { propOne, propTwo, children, ...props } = this.props;

<Component propOne={propOne} propTwo={propTwo} {...props}>
    {children}
</Component>

Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

Source: MDN

Upvotes: 133

HoldOffHunger
HoldOffHunger

Reputation: 20948

The spread operator is great, but I was surprised I hadn't discovered it in the tutorials, and then it took forever to track down a reliable source describing it. In case you were doubting how it works, here are the details in the official ReactJS POD, from a little article called JSX In Depth...

If you already have props as an object, and you want to pass it in JSX, you can use ... as a “spread” operator to pass the whole props object. These two components are equivalent:

 return <Greeting firstName="Ben" lastName="Hector" />;
}

function App2() {
 const props = {firstName: 'Ben', lastName: 'Hector'};
 return <Greeting {...props} />;
}```

And, of course, for your case, where you want to pass only some of the children...

const Button = props => {
 const { kind, ...other } = props;
 const className = kind === "primary" ? "PrimaryButton" : "SecondaryButton";
 return <button className={className} {...other} />;
};

In the example above, the kind prop is safely consumed and is not passed on to the element in the DOM. All other props are passed via the ...other object making this component really flexible. You can see that it passes an onClick and children props.

Source: ReactJS.org: JSX In Depth, Specifying the React Element Type, Spread Attributes.

For your specific case...

const {propOne, propTwo, ...newChildProps} = this.props;
<Component
    propOne={this.props.one}
    propTwo={this.props.two}
    {...newChildProps}
>{children}</Component>

Upvotes: 7

rashid behnam
rashid behnam

Reputation: 11

try to send whole properties as an Object under one property name. just like this

class ParentComponent extends Component{

    state={
      person:{
         id=1,
         name="rashid",
         family="behnam"
             }
         }
render(){
return <ChildComponent wholething={this.state.person} />
        }
}
//------------------------------------------
class ChildComponent extends Component{
render(){
     const {id,name,family}=this.props.wholething;
         return (
                <div someId={id}>
                   <h3>My name is :{name}</h3>
                   <h4>My family is :{family}</h4>
                </div>
                );
      }
}

Upvotes: 0

Maciej Chałapuk
Maciej Chałapuk

Reputation: 462

Filter them?

function without(props, keys) {
  return Object.keys(props)
    .filter((key) => keys.indexOf(key) !== -1)
    .reduce((retVal, key) => {
      retVal[key] = props[key];
    }, {});
}

<Component propOne={this.props.one} propTwo={this.props.two} {...without(this.props, ['one', 'two'])} >
  {this.props.children}
</Component>

Upvotes: 0

Related Questions