admin管理员组

文章数量:1278860

I'm currently building an AddProductPage ponent for my web app. It receives a bunch of props from its parent AddProductContainer and should divide those props among many smaller ponents 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 ponent, so I can see what my code will render on the page in a cleaner look. Like:

function AddProductPage(props) {

  const p1Props = {
    propsA: props.propsA,
    propsB: props.propsB
  }

  const p2Props = {
    propsC: props.propsC,
    propsD: props.propsD,
    propsE: props.propsE
  }

  return(
    <React.Fragment>
      <Component1 {..p1Props}/>    // <--- Easier to see what will render
      <Component2 {..p2Porps}/>
      // 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 p1Props = {
    propsA,
    propsB
  };

  const p2Props = {
    propsC,
    propsD,
    propsE
  };

  return(
    <React.Fragment>
      <Component1 {..p1Props}/>    // <--- Easier to see what will render
      <Component2 {..p2Porps}/>
      // 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.

I'm currently building an AddProductPage ponent for my web app. It receives a bunch of props from its parent AddProductContainer and should divide those props among many smaller ponents 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 ponent, so I can see what my code will render on the page in a cleaner look. Like:

function AddProductPage(props) {

  const p1Props = {
    propsA: props.propsA,
    propsB: props.propsB
  }

  const p2Props = {
    propsC: props.propsC,
    propsD: props.propsD,
    propsE: props.propsE
  }

  return(
    <React.Fragment>
      <Component1 {...p1Props}/>    // <--- Easier to see what will render
      <Component2 {...p2Porps}/>
      // 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 p1Props = {
    propsA,
    propsB
  };

  const p2Props = {
    propsC,
    propsD,
    propsE
  };

  return(
    <React.Fragment>
      <Component1 {...p1Props}/>    // <--- Easier to see what will render
      <Component2 {...p2Porps}/>
      // 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.

Share Improve this question edited Apr 8, 2019 at 10:41 cbdeveloper asked Apr 8, 2019 at 10:25 cbdevelopercbdeveloper 31.5k44 gold badges198 silver badges395 bronze badges 1
  • The answers might give you a run for your money, as I don't believe propsA, propsB etc are the props you want to go for, but they do match your question :) – Icepickle Commented Apr 8, 2019 at 10:29
Add a ment  | 

4 Answers 4

Reset to default 7

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 p1Props = {
    propsA,
    propsB
};

const p2Props = {
    propsC,
    propsD,
    propsE
};

console.log(p1Props);
console.log(p2Props);
.as-console-wrapper {
  max-height: 100% !important;
}


In ments 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 p1Props vs p2Props, 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 p1Props object, for example. Otherwise I would have to remember to destructure it first and then add it to the p1Props 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 p1Props and p2Props?

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 p1Props and p2Props within that block. But you can't use with in modern JavaScript.

You're probably best off doing what you're already doing:

const p1Props = {
    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 p1Props = pick(props, "propsA", "propsB");
  const p2Props = pick(props, "propsC", "propsD", "propsE");

  return(
    <React.Fragment>
      <Component1 {...p1Props}/>
      <Component2 {...p2Porps}/>
      // And so on...
    </React.Fragment>
  );
}

(Some would shoehorn that into a reduce call, but there's no need.)

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 p1Props = {
        propsA,
        propsB
    };

    const p2Props = {
        propsC,
        propsD,
        propsE
    };

    return(
        <React.Fragment>
            <Component1 {...p1Props}/> 
            <Component2 {...p2Porps}/>
            // And so on...
      </React.Fragment>
    );

}

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 constvalue, 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 ponent) makes it a lot cleaner.

class MyComponentName extends Component {
  getComponentOne = () => {
    const { propsA, propsB } = this.props;

    //Any other logic for ponent 1 can go here.

    return (
      <Component1
        propsA={propsA}
        propsB={propsB}
      />
    );
  };

  getComponentTwo = () => {
    const { propsC, propsD, propsE} = this.props;

    //Any other logic for ponent 2 can go here.

    return (
      <Component2
        propsC={propsC}
        propsD={propsD}
        propsE={propsE}
      />
    );
  };

  // Other ponent method getters

  addProductPage = () => (
    <React.Fragment>
      {this.getComponentOne()}
      {this.getComponentTwo()}
      // Get other ponent 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 ponents, as I don't know if your ponent has any other methods/ logic. As if you have other methods in your functional ponent, on each render those methods would get reinitiated, which again would be a big performance issue.

If you just have a functional ponent 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 ponents (If simply returning JSX)
  </React.Fragment>
);

Hope the above is of some help to you.

You can use:

function AddProductPage({propsA, propsB, propsC, propsD, propsE}) {

Or

const {propsA, propsB, propsC, propsD, propsE} = props

本文标签: javascriptDestructuring props dynamicallyStack Overflow