Cannot read property 'refs' of null react error react js

I'm using React js 0.14.3, I'm trying to create a Side Menu component using react but I don't know why I have an "Cannot read property 'refs' of null" when I use the refs like in the react documentation : https://facebook.github.io/react/docs/more-about-refs.html Can you help me please ?

'use strict';

    import React from 'react';
    import BaseComponent from './../../BaseComponent.react';
    import Menu from './SidePanelMenu';
    import MenuItem from './SidePanelMenuItem';

    class SidePanel extends BaseComponent {
        showLeft() {
            this.refs.leftmenu.show();
        }


        render() {
            return(
                <div>
                    <button onClick={this.showLeft}>Show Left Menu!</button>

                    <Menu ref="leftmenu" alignment="left">
                        <MenuItem hash="first-page">First Page</MenuItem>
                        <MenuItem hash="second-page">Second Page</MenuItem>
                        <MenuItem hash="third-page">Third Page</MenuItem>
                    </Menu>
                </div>
            );
        }
    }

    export default SidePanel;

Answers


You need to bind context of this.

The line where you are binding your onClick handler:

onClick={this.showLeft}

Needs to be:

onClick={this.showLeft.bind(this)}

Otherwise when you're calling showLeft it can't access this.


Change this:

<button onClick={this.showLeft}>Show Left Menu!</button>

To this:

<button onClick={::this.showLeft}>Show Left Menu!</button>`

Could be a this issue. try

showLeft = () => {
            this.refs.leftmenu.show();
        }

You can also bind it like this to avoid eslint error of No .bind() or Arrow Functions in JSX Props:

class SidePanel extends BaseComponent {
    constructor(props) {
        super(props);
        this.showLeft = this.showLeft.bind(this);
        this.state = {
            error: false,
        };
    }

    showLeft() {
        this.refs.leftmenu.show();
    }


    render() {
        return(
            <div>
                <button onClick={this.showLeft}>Show Left Menu!</button>

                <Menu ref="leftmenu" alignment="left">
                    <MenuItem hash="first-page">First Page</MenuItem>
                    <MenuItem hash="second-page">Second Page</MenuItem>
                    <MenuItem hash="third-page">Third Page</MenuItem>
                </Menu>
            </div>
        );
    }
}

Your code is written in ES6. Unlike ES5, there is no auto binding in ES6.

So you have to explicitly bind the function to the component instance using this.functionName.bind(this).

Like so:

<button onClick={this.showLeft.bind(this)}>Show Left Menu!</button>

Without binding, when you click on the button, the this on the button refers to the button itself and not the function. So JavaScript tries to find refs on the button element, which gives you that error.


Need Your Help

Android: Hide ActionBar, keep Tabs

java android android-actionbar

To keep this simple: I have tabs in my actionbar, but the action bar take up too much space. I want that extra space. I need a way to hide the action bar, yet keep my tabs. Is there anyway to do th...

NSFetchedResultsController with sections created by first letter of a string

iphone ios objective-c core-data

Learning Core Data on the iPhone. There seem to be few examples on Core Data populating a table view with sections. The CoreDataBooks example uses sections, but they're generated from full strings