美文网首页让前端飞Web前端之路
React 组件模版(受控&非受控)

React 组件模版(受控&非受控)

作者: gzgogo | 来源:发表于2019-07-23 13:36 被阅读3次

你可能不需要使用派生 state 一文出指出,当使用派生state时,书写不当很容易产生问题,所以建议任何数据,都要保证只有一个数据来源,而且避免直接复制它。但是这样就使一个组件要么受控,要么非受控,只能选其一,且为了提高灵活性,建议将组件实现为受控组件。

那么如何实现一个既受控又非受控的组件呢?下面将我的组件模版分享给大家:

其中关键是'value' in this.props的判断

import React, { PropTypes } from 'react';
import deepEqual from 'deep-equal';
import './style.less';

export default class MyComponent extends React.Component {
  static propTypes = {
    className   : PropTypes.string,
    value       : PropTypes.number
  };

  static defaultProps = {
    className    : '',
    defaultValue : 0,
    //value      : 0, //不能为value设置默认值,否则组件会被认为是受控组件
  };
  
  constructor(props) {
    super(props);

    this.state = {
      value: 'value' in props ? props.value : props.defaultValue
    };

    this.handleChange = this.handleChange.bind(this);
  }

  componentDidMount() {
  }

  componentWillReceiveProps(nextProps) {
    if ('value' in nextProps && !deepEqual(nextProps.value, this.props.value)) {
      this.setState({
        value: nextProps.value
      });
    }
  }

  render() {
    const { value, className } = this.state;

    let classes = className ? `my-component ${className}`: 'my-component';

    return (
      <div className={classes}>
        {value}
      </div>
    )
  }

  handleChange(value) {
    this.triggerChange(value);
  }

  triggerChange(value) {
    const { onChange } = this.props;

    if ('value' in this.props) {
      typeof onChange === 'function' && onChange(value);
    }
    else {
      this.setState({
        value: value
      }, ()=>typeof onChange === 'function' && onChange(value));
    }
  }
}

相关文章

网友评论

    本文标题:React 组件模版(受控&非受控)

    本文链接:https://www.haomeiwen.com/subject/lipolctx.html