【问题标题】:React functional component default props vs default parametersReact 功能组件默认道具与默认参数
【发布时间】:2018-05-26 06:15:52
【问题描述】:

在 React 功能组件中,这是设置默认道具的更好方法,使用Component.defaultProps,或在函数定义中使用默认参数,示例:

默认道具:

const Component = ({ prop1, prop2 }) => (
  <div></div>
)

Component.defaultProps = {
  prop1: false,
  prop2: 'My Prop',
}

默认参数:

const Component = ({ prop1 = false, prop2 = 'My Prop' }) => (
  <div></div>
)    

【问题讨论】:

  • @AbdennourTOUMI 请不要破坏默认的初始化语法!
  • 谢谢@Bergi。没关系!我认为这是一个错误的语法。是吗?
  • @AbdennourTOUMI 不,这是默认值的语法。您将其更改为对象文字语法,这对于参数中的字符串/布尔文字无效。

标签: javascript reactjs ecmascript-6


【解决方案1】:

功能组件上的defaultProps 将是eventually be deprecated (as per Dan Abramov, one of the core team),因此为了面向未来,值得使用默认参数。

【讨论】:

  • 那么,应该如何?
  • 这意味着,如果您关心项目的可维护性,请使用默认参数而不是“defaultProps”。实际上有人在我自己的回复中交叉引用了这个答案,请参阅stackoverflow.com/questions/41488537/…
  • 谢谢。对于那些使用 eslint 规则 "require-default-props" 并使用 ES6 默认参数的用户,您可以暂时禁用该规则:github.com/croutonn/next-template/issues/27 .eslintrc.json: "rules": { "react/require-default-props": “关闭”}
【解决方案2】:

一般情况下(ES6),第二种方式更好。

具体来说(在 React 上下文中),第一个更好,因为它是组件生命周期的主要阶段,即初始化阶段。

请记住,ReactJS 是在 ES6 之前发明的。

【讨论】:

  • 您能否详细说明在 React 上下文中使用 defaultProps 使其优于默认参数的意义?是否有一些关于如何在 React 中处理它们的基本原理,还是为了维护约定而更喜欢它?
  • @AlexanderNied defaultProps 在检查propTypes 之前 被评估。此外,正如@fforw 响应中所述,解构默认值不适用于此处。
  • @AlexanderNied 并且对于一些更复杂的连接组件来说,这个微小的差异非常重要,请参阅下面的答案。
  • 这个答案现在已经过时了,因为功能组件上的默认道具最终将被弃用(见下面我的答案)。
【解决方案3】:

第一个可能会导致一些难以调试的性能问题,尤其是在您使用 redux 时。

如果您正在使用对象、列表或函数,这些将是每次渲染时的新对象。 如果您有复杂的组件来检查组件身份以查看是否应该进行重新渲染,这可能会很糟糕。

const Component = ({ prop1 = {my:'prop'}, prop2 = ['My Prop'], prop3 = ()=>{} }) => {(
  <div>Hello</div>
)}

现在可以正常工作了,但是如果您有更复杂的组件和状态,例如带有数据库连接和/或 react useffect hooks 的 react-redux 连接的组件,以及组件状态,这可能会导致大量重新渲染。

通常更好的做法是单独创建默认道具对象,例如。

const Component = ({prop1, prop2, prop3 }) => (
  <div>Hello</div>
)

Component.defaultProps = {
  prop1: {my:'prop'},
  prop2: ['My Prop'],
  prop3: ()=>{}
}

const defaultProps = {
  prop1: {my:'prop'},
  prop2: ['My Prop'],
  prop3: ()=>{}
}
const Component = ({
  prop1 = defaultProps.prop1,
  prop2 = defaultProps.prop2
  prop3 = defaultProps.prop3
 }) => (
  <div>Hello</div>
)

【讨论】:

    【解决方案4】:

    无耻插件,我是with-default-props的作者。

    如果您是 TypeScript 用户,with-default-props 可能会对您有所帮助,它使用高阶函数来提供正确的组件定义和给定的 defaultProps。

    例如。

    import { withDefaultProps } from 'with-default-props'
    
    type Props = {
        text: string;
        onClick: () => void;
    };
    
    function Component(props: Props) {
        return <div onClick={props.onClick}>{props.text}</div>;
    }
    
    // `onClick` is optional now.
    const Wrapped = withDefaultProps(Component, { onClick: () => {} })
    
    
    function App1() {
        // ✅
        return <Wrapped text="hello"></Wrapped>
    }
    
    function App2() {
        // ✅
        return <Wrapped text="hello" onClick={() => {}}></Wrapped>
    }
    
    function App3() {
        // ❌
        // Error: `text` is missing!
        return <Wrapped onClick={() => {}}></Wrapped>
    }
    

    【讨论】:

      【解决方案5】:

      也许你会问,为什么不用props || value 而不是defaultProps

      class SomeComponent extends React.Component {
        render() {
          let data = this.props.data || {foo: 'bar'}
          return (
            <div>rendered</div>
          )
        }
      }
      
      // SomeComponent.defaultProps = {
      //   data: {foo: 'bar'}
      // };
      
      ReactDOM.render(
        <AddAddressComponent />,
        document.getElementById('app')
      )
      

      但请记住 defaultProps 使代码更具可读性,特别是如果您有更多 props 并使用 || 运算符控制它们可能会使您的代码看起来很丑

      【讨论】:

        【解决方案6】:

        这里是关于弃用defaultProps的官方公告。

        https://github.com/reactjs/rfcs/pull/107

        【讨论】:

        • 这不是答案。应该是评论。
        • @T3rm1 表示官方推荐默认参数。为什么你认为这不是答案?
        猜你喜欢
        • 2020-12-21
        • 2019-12-25
        • 2020-03-14
        • 2020-01-25
        • 2019-06-15
        • 2019-12-27
        • 2016-12-11
        • 2018-04-03
        • 1970-01-01
        相关资源
        最近更新 更多