代码之家  ›  专栏  ›  技术社区  ›  Yu Chen little_birdie

Redux connect()删除组件所需的函数[重复]

  •  1
  • Yu Chen little_birdie  · 技术社区  · 6 年前

    我很难弄清楚最好的策略是什么来保留我原来组件的功能(特别是 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 对象

    1 回复  |  直到 6 年前
        1
  •  4
  •   Matan Bobi    6 年前

    在使用Redux和ref时,应该传递以连接options参数 withRef (这是第四个参数)。 您的连接将如下所示: export default connect(mapStateToProps, null, null, { withRef: true })(Radio);

    然后,您将能够通过以下方式了解组件的功能: option.getWrappedInstance().setSelected(!selected);

    您可以查看react redux文档 here

    但我认为这种方法不是一种很好的方法,我不建议过度使用refs,也许可以尝试将所选内容作为父对象的道具传递 RadioGroup 为了得到更整洁的解决方案。