具有默认属性集的组件

时间:2014-12-15 19:13:06

标签: javascript attributes reactjs web-component

我正在寻找一种方法来设置具有一个属性的react组件的默认属性。而不是每次我使用具有相同属性的函数时重复。我想要一种方法来重用那些属性而不必将它放入它自己的组件中。

这是一个例子,即使每组中只有一个属性。想象一下,我有几个不同的预设,每个预设都有10个道具/属性,只需要调用一个属性,并为你填写所有属性。

var List = React.createClass({
  getDefaultProps: function(){
    var propSets = {
      "default":{
        "icon": "fa fa-wifi"
      },
      "fruits":{
        "icon": "fa fa-apple"
      },
      "vegetables":{
        "icon": "fa fa-tree"

      }
    }
    //setPropsViaProp
    if(typeof this.props.set === "undefined") return propSets["default"];
    return propSets[this.props.set];
  },
  render: function() {
    return (
      <div className="list">
        <i class="{ this.props.icon }"></i>
      </div>
    )
  }
});

<List set="fruits">
<List set="vegetables">

这是投掷

  

无法读取未定义

的属性'set'

我猜测道具尚未在getDefaultProps()

中定义

4 个答案:

答案 0 :(得分:1)

在您知道set属性的内容时,修改组件的道具为时已晚。

您可以改为使用mixin来安装获取这些属性的方法:

var PropSetsMixin = {
    getProp: function(name) {
        // Simplified implementation for the answer, use better one in production
        return this.propSets[this.props.set][name];
    }
};


var List = React.createClass({
    mixins: [PropSetsMixin],

    propSets: {
        "default":{
            "icon": "fa fa-wifi"
        },
        "fruits":{
            "icon": "fa fa-apple"
        },
        "vegetables":{
            "icon": "fa fa-tree"
        }
    },

    render: function() {
        return (
            <div className="list">
                <i className={this.getProp("icon")}></i>
            </div>
        )
    }
});

或者,如果你不喜欢函数调用:

var PropSetsMixin = {
    componentWillReceiveProps: function(props) {
        this._applyPropSets(props);
    },

    componentWillMount: function() {
        this._applyPropSets(this.props);
    },

    _applyPropSets: function(props) {
        var set = props.set || "default";
        this.propSet = this.propSets[set];
    }
};


var List = React.createClass({
    mixins: [PropSetsMixin],

    propSets: {
        "default":{
            "icon": "fa fa-wifi"
        },
        "fruits":{
            "icon": "fa fa-apple"
        },
        "vegetables":{
            "icon": "fa fa-tree"
        }
    },

    render: function() {
        return (
            <div className="list">
                <i className={this.propSet.icon}></i>
            </div>
        )
    }
});

答案 1 :(得分:1)

getDefaultProps只被调用一次,因此不起作用。你真正想做的是在你需要时计算道具。

var PropSetMixin = function(sets){
  return {
    getProps: function(){
        var set = this.props.set ? sets[this.props.set] : sets.default;
        return Object.assign({}, set, this.props);
    }
  }
}

var List = React.createClass({
  mixins: [PropSetMixin({
      "default":{
        "icon": "fa fa-wifi"
      },
      "fruits":{
        "icon": "fa fa-apple"
      },
      "vegetables":{
        "icon": "fa fa-tree"

      }
  })]
  render: function() {
    var props = this.getProps();

    return (
      <div className="list">
        <i class="{ props.icon }"></i>
      </div>
    )
  }
});

如果以后有一段时间,可以通过在componentWillMount和componentWillReceiveProps中缓存结果来优化这一点,而无需使用mixin更改组件。

答案 2 :(得分:0)

快速解决方案:检查if本身中的变量

if(this.props && typeof this.props.set === "undefined")

这样在尝试访问它之前,它会检查是否有一个名为this.props的变量

答案 3 :(得分:0)

根据docs,您无法依赖this.props内的getDefaultProps。可能希望在getInitialState中进行计算并将结果存储在某个组件级属性中。