简体   繁体   English

支持oneOf数组或React.js中的默认值

[英]prop oneOf array or default in React.js

I want to create a component with prop in an array or use default value: 我想在数组中使用prop创建一个组件或使用默认值:

<Component lang="en"/> // this.props.lang == en
<Component lang="fr"/> // this.props.lang == fr

My component is not yet translated in italian so <Component lang="it"/> display a nice warning message: 我的组件尚未翻译成意大利语,因此<Component lang="it"/>显示了一个不错的警告消息:

Warning: Failed prop type: Invalid prop `lang` of value `it` supplied to `Component`, expected one of ["en","fr"].

The language of my component is equal to it , and I want to be equal to en . 我组件的语言等于it ,并且我想等于en Any idea ? 任何想法 ?

import React from 'react';

const Component = React.createClass({
  propTypes: {
    lang: React.PropTypes.oneOf(['en', 'fr'])
  },
  getDefaultProps() {
    return {
      lang: 'en'
    };
  },
  render(){
    return (
      <h1>
        lang: {this.props.lang}
      </h1>
    );
  }
});

export default Component;

Here my tests : 这是我的测试:

import assert from 'assert';

import React from 'react';
import {mount} from 'enzyme';

import Component from './Component';

describe('<Component />', () => {
  it('get default prop', () => {
    const wrapper = mount(<Component />);
    assert.equal(wrapper.prop('lang'), 'en') // pass
  });
  it('get valid prop', () => {
    const wrapper = mount(<Component lang="fr"/>);
    assert.equal(wrapper.prop('lang'), 'fr') // pass
  });
  it('get invalid prop', () => {
    const wrapper = mount(<Component lang="it"/>);
    assert.equal(wrapper.prop('lang'), 'en') // fail
  });
});

The prop validation provided by React is really intended for debugging in development, not for production. React提供的prop验证实际上是用于开发中的调试,而不是用于生产。

For what you're trying to achieve, you should build a custom helper method to convert the value if it's not something you're expecting. 对于您要实现的目标,您应该构建一个自定义的辅助方法,以在不期望的情况下转换该值。

import React from 'react';

const VALID_LANGS = ['en', 'fr'];

const Component = React.createClass({
  propTypes: {
    lang: React.PropTypes.oneOf(VALID_LANGS)
  },
  getDefaultProps() {
    return {
      lang: 'en'
    };
  },
  render() {
    return (
      <h1>
        lang: {this.getLang()}
      </h1>
    );
  },
  getLang() {
    return VALID_LANGS.indexOf(this.props.lang) !== -1 ? this.props.lang : VALID_LANGS[0];
  }
});

export default Component;

You'll need to update your test though, since you can't check if the prop is correct. 不过,由于无法检查道具是否正确,因此您需要更新测试。 Instead, you'll need to either check that the output matches what you expect, or that a child component is rendered with the correct "en" prop value. 取而代之的是,您需要检查输出是否符合期望,或者用正确的“ en”属性值渲染子组件。

Here another solution with state and getInitialState 这是另一个使用state和getInitialState的解决方案

import React from 'react';

const DEFAULT_LANG = 'en';
const LOCALES = {
  en: {},
  fr: {}
};

const Component = React.createClass({
  propTypes: {
    lang: React.PropTypes.oneOf(Object.keys(LOCALES))
  },
  getInitialState(){
    const lang = this.props.lang in LOCALES ? this.props.lang : DEFAULT_LANG;
    return {
      lang: lang
    };
  },
  getDefaultProps() {
    return {
      lang: 'en'
    };
  },
  render(){
    return (
      <h1>
        lang: {this.state.lang}
      </h1>
    );
  }
});

export default Component;

and my tests : 和我的测试:

import assert from 'assert';

import React from 'react';
import {mount} from 'enzyme';

import Component from './Component';

describe('<Component />', () => {
  it('get default prop', () => {
    const wrapper = mount(<Component />);
    assert.equal(wrapper.state('lang'), 'en')
  });
  it('get valid prop', () => {
    const wrapper = mount(<Component lang="fr"/>);
    assert.equal(wrapper.state('lang'), 'fr')
  });
  it('get invalid prop', () => {
    const wrapper = mount(<Component lang="it"/>);
    assert.equal(wrapper.state('lang'), 'en')
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM