动态破坏道具?

时间:2019-04-08 10:25:17

标签: javascript reactjs

我目前正在为我的Web应用程序构建一个AddProductPage组件。它从其父级props接收到一堆AddProductContainer,并将这些props划分到页面上呈现的许多较小组件中。

示例:

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>
  );
}

我决定将完整的props对象划分为较小的对象,每个对象一个,以便可以更清晰地看到代码在页面上呈现的内容。喜欢:

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>
  );
}

我目前正在考虑是否有可能将所有props动态地分解(或其他方法)成单个变量,以便我可以这样写:

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>
  );

}

我该怎么做?

编辑

我想我的问题还不够清楚。但是,我所说的动态含义是在不知道props名称或有多少props的情况下破坏一切。有可能吗?

赞:

const {...props} = {...props}; // This is pseudo code

这样,我认为我的代码将尽可能干净。谢谢。

4 个答案:

答案 0 :(得分:5)

“一些将所有道具分解为单个变量的代码”将是简单的分解:

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

实时示例:

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;
}


在您澄清的评论中:

  

动态意思是在不知道道具名称或道具数量的情况下破坏一切。

我问您如何知道分别分配给comp1Propscomp2Props的内容,您说:

  

我仍然会决定并手动创建那些对象。但是,如果将一个新的prop传递给AddProductPage,我希望它可以被自动解构并可以将其添加到comp1Props对象中。否则,我将不得不记住首先对其进行解构,然后将其添加到comp1Props对象中。

所以问题是:您可以为propsAddProductPage的所有属性自动创建常量/变量,以便它们都可用于创建{{1} }和comp1Props

否,如果不使用在严格模式下(模块默认情况下已启用)不可用的令人困惑的功能(comp2Props),就无法做到这一点。如果可以使用with,则只需执行with并在该块中创建with (props) { /*...*/ }comp1Props。但是您不能在现代JavaScript中使用comp2Props

您最好做已经在做的事情:

with

但是,如果您想使其更短,可以给自己一个可重用的实用程序功能:

const comp1Props = {
    propsA: props.propsA,
    propsB: props.propsB
};

,然后在function pick(source, ...props) { const result = {}; for (const prop of props) { result[prop] = source[prop]; } } 中使用它:

AddProductPage

(有些人可能会horn脚到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> ); } 电话中,但是没有必要。)

答案 1 :(得分:2)

我参加聚会有点晚了,但是我想提一下如何使您的代码可读性和可维护性。您应该分离代码,从而分离关注点。

我个人认为您正在考虑自己所需的功能。对于每个Component1Component2Component3等。您将声明另一个const值,具体取决于您拥有多少会对性能产生影响。更重要的是,“让您拥有组件”以及传递的道具的布局如下图所示(不与组件内联)使它更加整洁。

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;

可以考虑的两个引号是C. Martin,他在他的书《清洁代码:敏捷软件技巧手册》中指出:

  

即使错误的代码也可以起作用。但是,如果代码不干净,它可能会使开发组织屈服。每年,由于编写不良的代码而浪费了无数的时间和大量的资源。但这不是必须的。

AND

  

“清洁代码是已处理的代码。有人花了一些时间使它保持简单和有序。他们已经适当注意细节。他们很在意。”

关于上面的示例,我还使用了类组件,因为我不知道您的组件是否还有其他方法/逻辑。好像您的功能组件中还有其他方法一样,在每次渲染时,这些方法都将重新启动,这又将是一个很大的性能问题。

如果您只有功能组件,并且不想分离代码/没有逻辑,并且只返回JSX,则可以按照以下方式进行操作。

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>
);

希望以上内容对您有所帮助。

答案 2 :(得分:1)

您可以做类似的事情

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>
    );

}

答案 3 :(得分:0)

您可以使用:

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

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

const comp1Props = {
        propsA,
        propsB
    } = props;

    const comp2Props = {
        propsC,
        propsD,
        propsE
    } = props;