Этот refs получает метод undefined в методе

Я пытаюсь использовать этот плагин в своем проекте https://github.com/rt2zz/react-native-drawer. Я мог бы правильно запустить пример, но проблема с его интеграцией.

Я получаю ошибку в методе openDrawer. "Не удается прочитать ящик свойств undefined"

Я предполагаю, что я не определяю и не использую класс правильно, как должно быть (я новичок в javascript OOP), так как в примере он использует React.createClass({ в отличие от моего как расширяющего Component и имеет конструктор.

Соответствующие коды из моего класса следующие.

class Search extends Component {

    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2
            })
        };
    }

    openDrawer(){
        this.refs.drawer.open()
    }

    getInitialState(){
        return {
          drawerType: 'overlay',

        }
    }

Render -

render() {
        if (this.state.isLoading) {
            return this.renderLoadingView();
        }

        var controlPanel = <MyControlPanel closeDrawer={() => {this.refs.drawer.close()}} />

        return (


            <View>
                <View style={styles.topBar}>

                    <Drawer
                        ref="drawer"
                        >
                        <MyMainView
                          />
                    </Drawer>

                    <Text style={styles.topBarMenu}>&#9776;</Text>
                    <Text style={styles.topBarTitle}>เงินปันผล</Text>
                    <Text style={styles.topBarRight}></Text>
                </View>

Ответ 1

Я думаю, что лучше, если вы вернетесь к использованию createClass. ES6 способ создания классов (расширений) имеет несколько недостатков над createClass: методы не связаны (т.е. "this" не обязательно указывает на объект), также вы не можете использовать миксины, которые очень полезны. Несвязанные методы - это проблема, с которой вы сталкиваетесь. Вы также можете обойти это, если у вас есть контроль над местом, где вызывается метод, и привязать метод (посмотрите на привязку метода в javascript, например здесь: http://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/)

Ответ 2

Есть лучший способ, чем положить this.openDrawer = this.openDrawer.bind(this) в конструктор Объявить метод openDrawer со стрелками:

openDrawer = () => {
  this.refs.drawer.open()
}

Ответ 3

Просто, чтобы это стало понятным для всех, при использовании ES6 class (вместо React.createClass) вам нужно привязать методы к this в конструкторе.

Пример

class Search extends Component {

    constructor(props) {
        super(props);

        this.state = {
            isLoading: true,
            dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2
            })
        };

        this.openDrawer = this.openDrawer.bind(this); //bind this to openDrawer
    } 
}

Примечание. Я думал, что добавлю этот ответ, так как ответ, помеченный как правильный, вернется к React.createClass. Также он упоминается в комментариях, но не совсем ясен.