Я хотел бы клонировать компонент реакции (по запросу - запускается нажатием кнопки). Клон должен иметь те же свойства, что и исходный компонент, но не зависеть от него. Ниже приведен пример моего дочернего компонента. Я хотел бы клонировать родительский компонент (содержащий несколько дочерних компонентов).
Клонированный компонент должен иметь такое же поведение, а дочерние элементы изначально должны иметь те же значения, что и оригинал.
Каков наилучший (рекомендуемый) способ клонирования компонента?
import React from 'react';
import PropTypes from 'prop-types';
export default class MySelector extends React.Component {
constructor(props) {
super(props);
this.handleChangeEvent = this.handleChangeEvent.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;
}
handleChangeEvent(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.handleChangeEvent}
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,
};
К вашему сведению, вы знали, что у вас могут быть такие реквизиты: const {errorMsg, name, apiPath, valueName} = this.props; ?
@ MichalCholewiński - Спасибо, не придумал использовать там деструктуризацию, она прекрасно очищает код! Подробнее по теме в этом посте: stackoverflow.com/questions/39668122/…
@ Андрей - Спасибо! Я дам ему попробовать.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже,
React.cloneElementможет быть полезен. Может быть, их множество вthis.state?