react-native-dropdown-picker打开时报this.setState未定义错误
问题现象
学习React Native过程中使用react-native-dropdown-picker实现下拉菜单功能,参照类组件示例编写代码后,点击下拉选择器触发打开操作时抛出如下错误:
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'this.setState')] at node_modules\react-native-dropdown-picker\src\components\Picker.js:369:10 in Picker at node_modules\react-native-dropdown-picker\src\components\Picker.js:636:34 in __onPress at node_modules\@babel\runtime\helpers\regeneratorRuntime.js:86:13 in tryCatch at node_modules\@babel\runtime\helpers\regeneratorRuntime.js:66:31 in <anonymous> at node_modules\@babel\runtime\helpers\regeneratorRuntime.js:86:13 in tryCatch at node_modules\@babel\runtime\helpers\regeneratorRuntime.js:124:27 in invoke at node_modules\@babel\runtime\helpers\regeneratorRuntime.js:130:16 in PromiseImpl.resolve.then$argument_0 at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0 at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:248:12 in _allocateCallback$argument_0 at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:112:14 in _callTimer at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:162:14 in _callReactNativeMicrotasksPass at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:413:41 in callReactNativeMicrotasks at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:391:6 in __callReactNativeMicrotasks at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:133:6 in __guard$argument_0 at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:368:10 in __guard at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:132:4 in flushedQueue
原有实现代码如下:
import React from "react"; import DropDownPicker from 'react-native-dropdown-picker'; export class GroupSelector extends React.Component { constructor(props) { super(props); this.state = { open : false, value : 'One', items: [ 'One', 'Two', 'Three'] }; this.setValue = this.setValue.bind(this); } setOpen(isOpen) { console.log("Open: " + isOpen); this.setState({ open : isOpen }); } setValue(callback) { this.setState(state => ({ value: callback(state.value) })); } setItems(callback) { this.setState(state => ({ items: callback(state.items) })); } render() { const { open, value, items } = this.state; return ( <DropDownPicker open={open} value={value} items={items} setOpen={this.setOpen} setValue={this.setValue} setItems={this.setItems} /> ) } };
触发异常时setOpen方法内的日志可正常输出Open: true。
问题原因
两个问题共同导致报错:
- 类方法this绑定不全:JavaScript类的原型方法不会自动绑定组件实例的
this上下文,当你把方法引用作为props传递给子组件、尤其是被异步逻辑调用时,方法内的this会指向undefined,访问this.setState就会抛出类型错误。你的代码中仅在构造函数里绑定了setValue方法,setOpen、setItems均未做绑定。setOpen内的首次日志能打印,是因为第一次同步调用时上下文暂未丢失,但后续库内部异步流程调用未绑定的方法时就会触发报错。 - items属性格式错误:
react-native-dropdown-picker要求items属性必须是包含label(显示文本)和value(选中值)字段的对象数组,你传入的纯字符串数组不符合格式要求,会导致库内部状态计算异常。
修复方案
- 在构造函数中补全
setOpen、setItems方法的this绑定 - 将items数组修改为库要求的对象格式
修复后的完整代码:
import React from "react"; import DropDownPicker from 'react-native-dropdown-picker'; export class GroupSelector extends React.Component { constructor(props) { super(props); this.state = { open : false, value : 'One', // 修改items为要求的对象格式 items: [ {label: 'One', value: 'One'}, {label: 'Two', value: 'Two'}, {label: 'Three', value: 'Three'} ] }; // 补全所有方法的this绑定 this.setOpen = this.setOpen.bind(this); this.setValue = this.setValue.bind(this); this.setItems = this.setItems.bind(this); } setOpen(isOpen) { console.log("Open: " + isOpen); this.setState({ open : isOpen }); } setValue(callback) { this.setState(state => ({ value: callback(state.value) })); } setItems(callback) { this.setState(state => ({ items: callback(state.items) })); } render() { const { open, value, items } = this.state; return ( <DropDownPicker open={open} value={value} items={items} setOpen={this.setOpen} setValue={this.setValue} setItems={this.setItems} /> ) } };
内容的提问来源于stack exchange,提问作者Marcel Schulte
相关产品推荐
相关产品推荐

