Этот 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}>☰</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
. Также он упоминается в комментариях, но не совсем ясен.