使用RFX Stack+Mobx时Observable未触发组件渲染问题求助
问题分析与解决方案
看起来你遇到的问题主要来自两个方面:Mobx可观察对象的类型定义不匹配,以及渲染逻辑的判断错误,导致拖放后组件没有正确更新并显示图片。我们一步步来修复:
1. 修正Observable类型定义
你初始把profilePhoto定义为对象{},但Dropzone的acceptedFiles是一个数组(即使multiple={false},返回的依然是单元素数组)。Mobx对对象和数组的追踪方式不同,应该把它定义为可观察数组,这样Mobx才能正确追踪数组的变化并触发组件重渲染:
@observable profilePhoto = []; // 改为数组,而非对象
2. 修复渲染逻辑的判断错误
你的渲染代码里判断this.profilePhoto !== undefined,但初始值是[](之前是{}),这个条件永远为真。如果初始是{}的话,执行map方法会直接报错(因为对象没有map),导致后续渲染异常。我们应该判断数组的长度:
<div> {this.profilePhoto.length > 0 ? this.profilePhoto.map((file, index) => ( <img key={index} src={file.preview} alt="Preview" /> )) : null} </div>
注意加上key属性,符合React列表渲染的要求,避免警告。
3. 优化OnDrop事件的处理
另外,你在onDrop里的console.log写法有误,因为acceptedFiles是数组,数组本身没有preview属性,应该取数组的第一个元素:
onDrop(acceptedFiles, rejectedFiles) { // 直接赋值数组,或者用Mobx数组的replace方法保持可观察引用 this.profilePhoto = acceptedFiles; // 修正console.log console.log(this.profilePhoto[0]?.preview); }
如果你想保持profilePhoto的可观察数组引用不改变,可以用Mobx数组的replace方法:
this.profilePhoto.replace(acceptedFiles);
完整修正后的代码
@inject('store') @observer @authorize class Settings extends Component { static fetchData() {} @observable profilePhoto = []; // 改为可观察数组 static propTypes = { store: PropTypes.object, t: PropTypes.func, }; componentWillMount() { const { t } = this.props; dispatch('ui.appBar.setTitle', t('title.profile')); dispatch('ui.appBar.setSubPage', true); } onDrop(acceptedFiles, rejectedFiles) { this.profilePhoto = acceptedFiles; console.log(this.profilePhoto[0]?.preview); } render() { const { ui } = this.props.store; return ( <div className="main"> <Dropzone onDrop={this.onDrop.bind(this)} className='dropzone' activeClassName='active-dropzone' multiple={false}> <div>Drag and drop or click to select a 550x550px file to upload.</div> </Dropzone> <div> {this.profilePhoto.length > 0 ? this.profilePhoto.map((file, index) => ( <img key={index} src={file.preview} alt="Profile preview" /> )) : null} </div> </div> ); } } export default translate('settings')(Settings);
这样修改后,当你拖放文件时,profilePhoto会被正确更新为可观察数组,Mobx会触发组件重渲染,图片就能正常显示了。
内容的提问来源于stack exchange,提问作者Mindaugas Nakrosis
相关产品推荐
相关产品推荐

