你如何在React中为嵌套形状提供默认道具?

时间:2016-06-30 12:44:39

标签: javascript reactjs

React有没有办法为某个形状的嵌套数组提供默认道具?

鉴于以下示例,我可以看到我的第一次尝试,但这并不像预期的那样工作。

static propTypes = {
    heading: PT.string,
    items: PT.arrayOf(PT.shape({
        href: PT.string,
        label: PT.string,
    })).isRequired,
};

static defaultProps = {
    heading: 'this works',
    items: [{
        href: '/',
        label: ' - this does not - ',
    }],
};

在这个例子中,我希望如下:

// Given these props
const passedInProps = {
    items: [{ href: 'foo', href: 'bar' }]
};

// Would resolve to:
const props = {
    heading: 'this works',
    items: [
      { href: 'foo', label: ' - this does not - ' },
      { href: 'bar', label: ' - this does not - ' },
    ]
};

2 个答案:

答案 0 :(得分:21)

没有。默认道具只是浅层合并。

但是,一种方法可能是为每个项目设置一个子组件。这样,每个Child组件都会从item数组中接收一个对象,然后默认道具将按预期合并。

例如:

var Parent = React.createClass({

  propTypes: {
    heading: React.PropTypes.string,
    items: React.PropTypes.arrayOf(React.PropTypes.shape({
      href: React.PropTypes.string,
      label: React.PropTypes.string,
    })).isRequired
  },

  getDefaultProps: function() {
    return {
      heading: 'this works',
      items: [{
        href: '/',
        label: ' - this does not - ',
      }],
    };
  },

  render: function() {
    return (
      <div>
        {this.props.item.map(function(item) {
          return <Child {...item} />
        })}
      </div>
    );
  }

});

var Child = React.createClass({

  propTypes: {
    href: React.PropTypes.string,
    label: React.PropTypes.string
  },

  getDefaultProps: function() {
    return {
      href: '/',
      label: ' - this does not - '
    };
  },

  render: function() {
    return (
      <div />
        <p>href: {this.props.href}</p>
        <p>label: {this.props.label}
      </div>
    );
  }

});

答案 1 :(得分:0)

您可以使用吸气剂代替调用this.props。您必须要有很多商品,这才是一种昂贵的方法。您还可以像下面一样修改items,然后将其设置为状态,但是React建议不要使用deriving state from props

class Foo extends React.Component {
  static propTypes = {
    heading: PropTypes.string,
    items: PropTypes.arrayOf(PropTypes.shape({
      href: PropTypes.string,
      label: PropTypes.string,
    })).isRequired
  }

  static defaultLabel = ' - this does not - '
  static defaultHref = '/'

  get items() {
    return this.props.items.map((item) => ({
      href: item.href || this.defaultHref,
      label: item.label || this.defaultLabel,
    }));
  }

  render() {
    return (
      <div>
        {this.items.map(({href, label}) => <a href={href}>{label}</a>)}
      </div>
    );
  }
}