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

Posted

技术标签:

【中文标题】如何在 React 组件上设置组件默认道具【英文标题】:How to set component default props on React component 【发布时间】:2016-12-11 17:39:30 【问题描述】:

我使用下面的代码在 React 组件上设置默认道具,但它不起作用。在render() 方法中,我可以看到输出“未定义的道具”打印在浏览器控制台上。如何为组件 props 定义默认值?

export default class AddAddressComponent extends Component 

render() 
   let provinceList,cityList = this.props
    if(cityList === undefined || provinceList === undefined)
      console.log('undefined props')
    
    ...


AddAddressComponent.contextTypes = 
  router: React.PropTypes.object.isRequired


AddAddressComponent.defaultProps = 
  cityList: [],
  provinceList: [],


AddAddressComponent.propTypes = 
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,

【问题讨论】:

【参考方案1】:

您忘记关闭Class 括号。

class AddAddressComponent extends React.Component 
  render() 
    let provinceList,cityList = this.props
    if(cityList === undefined || provinceList === undefined)
      console.log('undefined props')
     else 
      console.log('defined props')
    

    return (
      <div>rendered</div>
    )
  


AddAddressComponent.contextTypes = 
  router: React.PropTypes.object.isRequired
;

AddAddressComponent.defaultProps = 
  cityList: [],
  provinceList: [],
;

AddAddressComponent.propTypes = 
  userInfo: React.PropTypes.object,
  cityList: React.PropTypes.array.isRequired,
  provinceList: React.PropTypes.array.isRequired,


ReactDOM.render(
  <AddAddressComponent />,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app" />

【讨论】:

【参考方案2】:

对于那些使用类似 babel stage-2 或 transform-class-properties 的人:

import React,  PropTypes, Component  from 'react';

export default class ExampleComponent extends Component 
   static contextTypes = 
      // some context types
   ;

   static propTypes = 
      prop1: PropTypes.object
   ;

   static defaultProps = 
      prop1:  foobar: 'foobar' 
   ;

   ...



更新

从 React v15.5 开始,PropTypes 已从 React 主包 (link) 中移出:

import PropTypes from 'prop-types';

编辑

正如@johndodo 所指出的,static 类属性实际上不是 ES7 规范的一部分,而是目前仅受 babel 支持。更新以反映这一点。

【讨论】:

感谢您的回答,但我想了解更多有关它的信息,因此查看了react/native doc 并找不到它们,该文档在哪里? 我不认为它在 React 文档中明确显示,但如果你理解 static 类变量是什么是有意义的,所以我建议阅读它们 on MDN。基本上,文档中的语法与此等效,因为两者都将有关道具的信息添加到类本身,而不是单个实例。 导入改为:import PropTypes from 'prop-types'; @treyhakanson MDN 链接只讨论静态方法,而不是变量。除了Babel,我找不到静态类变量的引用。这是一个被接受的 ES7 属性吗?【参考方案3】:

首先,您需要将您的类与其他扩展分开,例如您不能在 class 内扩展 AddAddressComponent.defaultProps,而是将其移到外面。

我还建议您阅读 Constructor 和 React 的生命周期:请参阅 Component Specs and Lifecycle

这是你想要的:

import PropTypes from 'prop-types';

class AddAddressComponent extends React.Component 
  render() 
    let  provinceList, cityList  = this.props;
    if(cityList === undefined || provinceList === undefined)
      console.log('undefined props');
    
  


AddAddressComponent.contextTypes = 
  router: PropTypes.object.isRequired
;

AddAddressComponent.defaultProps = 
  cityList: [],
  provinceList: [],
;

AddAddressComponent.propTypes = 
  userInfo: PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,


export default AddAddressComponent;

【讨论】:

您确定他们需要constructorcomponentWillReceiveProps 吗?在我看来,OP 只是忘记了他们的类声明的右括号。 @ivarni 不一定,但重要的是他了解生命周期、构造函数和类扩展。这样他就会知道自己在做什么。所以我添加了一些外部链接 很公平,我只是认为说 “你需要” 并不完全正确。我宁愿说“您可以添加这些方法来观察生命周期”。否则,很好的答案:)【参考方案4】:

你也可以使用解构赋值。

class AddAddressComponent extends React.Component 
  render() 

    const 
      province="insertDefaultValueHere1",
      city="insertDefaultValueHere2"
     = this.props

    return (
      <div>province</div>
      <div>city</div>
    )
  

我喜欢这种方法,因为您不需要编写太多代码。

【讨论】:

我在这里看到的问题是您可能希望在多个方法中使用默认道具。【参考方案5】:

如果您使用的是函数式组件,您可以在解构赋值中定义默认值,如下所示:

export default ( children, id="menu", side="left", image=menu ) => 
  ...
;

【讨论】:

【参考方案6】:

使用静态的 defaultProps,例如:

export default class AddAddressComponent extends Component 
    static defaultProps = 
        provinceList: [],
        cityList: []
    

render() 
   let provinceList,cityList = this.props
    if(cityList === undefined || provinceList === undefined)
      console.log('undefined props')
    
    ...


AddAddressComponent.contextTypes = 
  router: React.PropTypes.object.isRequired


AddAddressComponent.defaultProps = 
  cityList: [],
  provinceList: [],


AddAddressComponent.propTypes = 
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,

取自: https://github.com/facebook/react-native/issues/1772

如果您想检查类型,请查看如何在 treyhakanson 或 Ilan Hasanov 的答案中使用 PropTypes,或查看上述链接中的许多答案。

【讨论】:

【参考方案7】:

您可以使用类名设置默认道具,如下所示。

class Greeting extends React.Component 
  render() 
    return (
      <h1>Hello, this.props.name</h1>
    );
  


// Specifies the default values for props:
Greeting.defaultProps = 
  name: 'Stranger'
;

您可以使用来自 link 的 React 推荐方式获取更多信息

【讨论】:

【参考方案8】:

对于函数类型道具,您可以使用以下代码:

AddAddressComponent.defaultProps = 
    callBackHandler: () => 
;

AddAddressComponent.propTypes = 
    callBackHandler: PropTypes.func,
;

【讨论】:

【参考方案9】:
class Example extends React.Component 
  render() 
    return <h1>this.props.text</h1>;
  


Example.defaultProps =  text: 'yo' ; 

【讨论】:

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

react-native 中的小问题活动指标 |组件 |组件内的道具 |道具 |设置状态

Typescript & React:在组件之间传递道具与默认道具

如何将值从组件传递给道具并设置状态

如何在 AngularJS 中实现组件组合(类似于 React 渲染道具模式)?

道具React发生变化时如何渲染组件?

如何将道具传递给 react-router 1.0 组件?