克隆React组件的最佳方法(按需)

时间:2018-03-29 07:17:25

标签: javascript reactjs components clone

我想克隆一个反应组件(按需点击 - 按下按钮触发)。克隆应具有与原始组件相同的属性,但不依赖于它。下面是我的子组件的示例。我想克隆父组件(包含许多子组件)。

克隆的组件应具有相同的行为,并且子项最初应具有与原始组件相同的值。

克隆组件的最佳(推荐)方法是什么?

import React from 'react';
import PropTypes from 'prop-types';

export default class MySelector extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.componentDidMount = this.componentDidMount.bind(this);
    this.makeApiCall = this.makeApiCall.bind(this);

    this.state = {
      data : [],
      hasData : false,
      errorMsg : null
    };

    this.errorMsg = props.errorMsg;
    this.name = props.name || '';
    this.label = props.label;
    this.apiPath = props.apiPath;
    this.keyName = props.keyName;
    this.valueName = props.valueName;
    this.changeFunction = props.changeFunction;
  }

  handleChange(e){
    const newValue = e.target.value.trim();
    const newText = e.target[e.target.selectedIndex].text.trim();
    const error = this.changeFunction(this.name, newValue, newText);
    this.setState( () => ( { errorMsg : error } ));
  }

  makeApiCall(){
    let headers = new Headers();
    headers.append('Accept', 'application/json');
    headers.append('Content-Type', 'application/json');
    fetch(`${this.apiPath}`, {headers: headers})
      .then(res => res.json() )
      .then(data => {
        const onlyOneOption = (data.value.length==1);
        const selectData = (onlyOneOption) ? data.value : [{name:'Select an option', genericKey:1337}].concat(data.value);
        if(onlyOneOption){
          this.changeFunction(this.name, selectData[0][this.valueName], selectData[0][this.keyName]);
        }
        this.setState({data:selectData, hasData:true});
      }); 
  }

  componentDidMount() {
    this.makeApiCall();
  }

  render() {
    return(
      <div className="option">
        {(this.label) && 
            <div className="option__text">
              <h3>{this.label}</h3>
            </div>
        }
        <div>
          {(!this.state.hasData && this.isAccessible) && <p>Loading...</p>}
          {(!this.isAccessible) && <select ref={this.name} className="add-option__input"><option key="dummy">...</option></select>}
          <select 
            ref={this.name} 
            defaultValue="null" 
            name={this.name} 
            id={this.name} required
            onChange={this.handleChange}
            className="add-option__input"
            style={(this.state.hasData) ? {display:'inline'} : {display:'none'}}
          >
            {(this.state.hasData) && 
              this.state.data.map( ds => <option key={ds[this.keyName]?ds[this.keyName]:ds.genericKey} value={ds[this.keyName]}>{ds[this.valueName]}</option>)
            }
          </select>
        </div>
      </div>
    );
  }
}
MySelector.defaultProps = {
  errorMsg: '',
  name: 'default', 
  label: 'Default',
  apiPath: '/rest/api/uri', 
  keyName: 'key',
  valueName: 'value'
};
MySelector.propTypes = {
  errorMsg: PropTypes.string,
  name: PropTypes.string,
  label: PropTypes.string,
  apiPath: PropTypes.string,
  keyName: PropTypes.string,
  valueName: PropTypes.string,
  changeFunction: PropTypes.func,
};

0 个答案:

没有答案