我很难弄清楚最好的策略是什么来保留我原来组件的功能(特别是
setSelected()
当使用Redux将其包装为高阶函数时
connect()
。我正在为我的前端应用程序的单选按钮使用一组很棒的组件:
Radio.js
:
class Radio extends React.Component {
constructor(props) {
super(props);
this.state = {selected: props.selected};
}
toggle() {
console.log(this.context)
const {onChange} = this.context.radioGroup;
const selected = !this.state.selected;
this.setState({selected});
// this.props.changeRadioGroupState(this.props.option);
onChange(selected, this);
}
setSelected(selected) {
this.setState({selected});
}
render() {
const activeStyle = {
opacity: 0.1
}
const grayStyle = {
opacity: 0.5
}
let classname = 'form__big_button'
return (
<button type="button"
className={classname}
onClick={this.toggle.bind(this)}
style={this.state.selected ? activeStyle : grayStyle }>
{this.props.option}
</button>
);
}
}
Radio.contextTypes = {
radioGroup: React.PropTypes.object
};
它有一个名为
RadioGroup.js
:
import React from 'react';
class RadioGroup extends React.Component {
constructor(props) {
super(props);
this.options = [];
this.changeRadioGroupState = this.changeRadioGroupState.bind(this);
}
getChildContext() {
const {name} = this.props;
return {radioGroup: {
name,
onChange: this.onChange.bind(this)
}};
}
changeRadioGroupState(selectedOption){
this.setState({selectedOption: selectedOption});
}
onChange(selected, child) {
console.log(this.options)
this.options.forEach(option => {
if (option !== child) {
option.setSelected(!selected);
}
});
}
render() {
let children = React.Children.map(this.props.children, child => {
let newElement = React.cloneElement(child, {
ref: (component => {this.options.push(component);})
});
return newElement;
});
return <div className="radio-group">{children}</div>;
}
}
RadioGroup.childContextTypes = {
radioGroup: React.PropTypes.object
};
export default RadioGroup;
总之,它的渲染非常简单:
<RadioGroup>
<Radio id="1" selected={true} option="Opt1"/>
<Radio id="2" selected={false} option="Opt2"/>
</RadioGroup>
但是,我想连线
Radio
到我的Redux商店,以便更新所选单选按钮:
const mapStateToProps = (state) => {
return {searchType: state.searchType}
}
export default connect(mapStateToProps)(Radio);
但是,这会导致浏览器出现错误:
Uncaught TypeError: option.setSelected is not a function
at eval (RadioGroup.js?6ccb:27)
at Array.forEach (<anonymous>)
at RadioGroup.onChange (RadioGroup.js?6ccb:25)
at Radio.toggle (Radio.js?9dd4:17)
at Object.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js?9efc:71)
at executeDispatch (EventPluginUtils.js?68fe:79)
at Object.executeDispatchesInOrder (EventPluginUtils.js?68fe:102)
at executeDispatchesAndRelease (EventPluginHub.js?daec:43)
at executeDispatchesAndReleaseTopLevel (EventPluginHub.js?daec:54)
at Array.forEach (<anonymous>)
这显然是
connect()
组件包装我的
无线电广播
组件-它不再公开
setSelected()
作用使用Redux将原始组件包装到高阶组件中时,保留其功能的最佳方法是什么
connect()
作用
我试过了
this.setSelected = this.setSelected.bind(this)
在构造函数中绑定,但它看起来像
connect()
函数返回完全不同类型的对象-a
Connect
对象