Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have the following 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));

which is used in this 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));

And I can't get the ref of the object MatchBox. I tried with this.refs.matchBox and is null, also tried getting directly from ref(ref={(r) => { // r is null } }) and I don't know what to try anymore. I'm using react-router-dom 4 and I don't know if function withRouter affect the outcome component.

like image 728
Mihai Avatar asked Jun 21 '17 15:06

Mihai


1 Answers

It's not pretty, but I think this is the solution. withRouter exposes the child ref via a wrappedComponentRef callback, which gets us to the connect hoc. That exposes its child ref via getWrappedInstance if you pass the withRef attribute as you did. So you just have to combine both of those.

class GameBox extends React.Component {    
    matchboxRefCallback = (connectHOC) => {
        this.matchboxRef = connectHOC ? connectHOC.getWrappedInstance() : null;
    }
    render() {
        return <MatchBox wrappedComponentRef={this.matchboxRefCallback}/>;
    }
}
like image 184
Alex Guerra Avatar answered Nov 05 '22 21:11

Alex Guerra