在使用 Redux、React 和 react-router 时从动态组件获取 ref-dom 4.x

Getting the ref from a dynamic component when using Redux, React and react-router-dom 4.x

我有以下class

class MatchBox extends React.Component {
    constructor(props) {
        super(props);

        this.countdownHandler = null;
        this.showBlocker = true;

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

    start() {
        ...
    }

    render() {
        ...

        return (
            <div style={ styles.mainContainer } className="fluid-container">
                ...
            </div>
        );
    }
};

function mapStateToProps(state) {
    ...
}

function matchDispatchToProps(dispatch) {
    ...
}

export default withRouter(connect(mapStateToProps, matchDispatchToProps, null, { withRef: true })(MatchBox));

在这个class

中使用
class GameBox extends React.Component {
    constructor(props) {
        super(props);

        ...
    }

    render() {
        var mainElement = null;
        switch(this.props.mainElement.element) {
            case 'SEARCHING': mainElement = <SearchingBox gameType={ this.props.gameType }/>; break;
            case 'MATCH': mainElement = <MatchBox ref='matchBox'/>; break;

            default: mainElement = <SearchingBox/>;
        }

        return (
            <div style={ styles.mainContainer } className="fluid-container">
                { mainElement }
            </div>
        );
    }
};

function mapStateToProps(state) {
    ...
}

function matchDispatchToProps(dispatch) {
    ...
}

export default withRouter(connect(mapStateToProps, matchDispatchToProps, null, { withRef: true })(GameBox));

而且我无法获取对象 MatchBox 的引用。我尝试使用 this.refs.matchBox 并且为空,也尝试直接从 ref(ref={(r) => { // r is null } }) 获取,但我不知道该尝试什么了。 我正在使用 react-router-dom 4,我不知道函数 withRouter 是否影响结果组件。

这不是很好,但我认为这是解决方案。 withRouter 通过 wrappedComponentRef 回调公开子引用,这让我们进入 connect hoc。如果您像您一样传递 withRef 属性,则通过 getWrappedInstance 公开其子引用。所以你只需要将两者结合起来。

class GameBox extends React.Component {    
    matchboxRefCallback = (connectHOC) => {
        this.matchboxRef = connectHOC ? connectHOC.getWrappedInstance() : null;
    }
    render() {
        return <MatchBox wrappedComponentRef={this.matchboxRefCallback}/>;
    }
}

更简洁的解决方案是创建一个 HOC。这会将引用转发给实际组件

const matchBoxHOC = (WrappedComponent) => {

    class MatchBoxHOC extends React.Component {
        render() {
            const { forwardRef, ...rest } = this.props;
            return <WrappedComponent {...rest} ref={forwardRef} />;
        }
    }

    const WithRouterMatchBoxHOC = withRouter(MatchBoxHOC, { withRef: true });

    return React.forwardRef((props, ref) => {
        return <WithRouterMatchBoxHOC {...props} forwardRef={ref} />;
    });
}

来电就好

export default matchBoxHOC(connect(mapStateToProps, matchDispatchToProps, null, { withRef: true })(MatchBox));