React 功能组件默认道具与默认参数

Posted

技术标签:

【中文标题】React 功能组件默认道具与默认参数【英文标题】:React functional component default props vs default parameters 【发布时间】: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 不,这是默认值的语法。您将其更改为对象文字语法,这对于参数中的字符串/布尔文字无效。 【参考方案1】:

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

【讨论】:

那么,应该如何? 这意味着,如果您关心项目的可维护性,请使用默认参数而不是“defaultProps”。实际上有人在我自己的回复中交叉引用了这个答案,请参阅***.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 表示官方推荐默认参数。为什么你认为这不是答案?

以上是关于React 功能组件默认道具与默认参数的主要内容,如果未能解决你的问题,请参考以下文章

Eslint:功能组件中的默认道具问题(Typescript - React)

React Typescript 类组件默认道具接口

React - 解构时的 defaultProps 与 ES6 默认参数(性能问题)

如何在 React 组件上设置组件默认道具

使用 TypeScript 3 扩展道具的 React 组件中的默认属性值

使用默认值键入对象参数