typescript - 为什么@observable 属性更改不会触发组件重新渲染?
问题描述
我正在尝试在 React-Native、TypeScript 和 Mobx for Android 中做一个家庭作业项目。在互联网上搜索答案超过 5 小时后,我仍然无法弄清楚为什么我的组件在 @observable 属性更改时不会自动重新渲染。
我正在使用 Expo 进行调试。我尝试更改 package.json 中的版本,并尝试了 .babelrc 文件的不同配置。我使用 react-native run-android cmd 运行该应用程序 - 结果仍然相同。说不上是bug,还是我在package.json里没有配置好,还是不知道怎么用Mobx。收到来自服务器的数据,我尝试在 5 秒后强制更新并呈现数据。
这是我的组件:
import {inject, observer} from "../../node_modules/mobx-react/native";
@inject('store') @observer
export class MasterView extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
}
componentWillMount() {
if (this.props.store.dataIsFromLocalStorage) {
this.props.store.sync();
}
//setTimeout(()=>this.forceUpdate(), 5000);
}
render() {
return (
<View style={this.props.style}>
{
this.props.store.albums == undefined ?
<ActivityIndicator size="large"/> :
<FlatList data={this.props.store.albums} keyExtractor={(item, index) => item.id.toString()}
renderItem={({item}) => <AlbumMasterView album={item}/>}/>
}
<Button text={""} icon={"add"} onPress={()=>this.props.store.crtSelectedAlbum = Album.emptyAlbum()}
style={{container: styles.addButton}}/>
</View>
);
}
}
这里是商店:
import {action, observable} from "mobx";
export class Store {
private serverProxy: ServerProxy = serverProxyInstance;
private localStorage: LocalStorage = localStorageInstance;
@observable public albums: Album[] = undefined;
@observable public dataIsFromLocalStorage: boolean = false;
@observable public crtSelectedAlbum: Album = undefined;
constructor() {
this.serverProxy.connectWs(undefined, () => {
this.loadAlbums()
});
this.loadAlbums();
}
private loadAlbums = () => {
this.serverProxy.getAlbums()
.then((albums) => {
this.handleAlbumsHaveArrived(albums);
this.localStorage.clear()
.then(() => this.localStorage.storeAlbums(albums));
this.dataIsFromLocalStorage = false;
})
.catch((error) => {
this.localStorage.getAlbums()
.then((albums) => this.handleAlbumsHaveArrived(albums))
.then(() => this.dataIsFromLocalStorage = true)
.catch(() => Alert.alert("Data load error", "No data could be loaded"));
});
};
@action private handleAlbumsHaveArrived = (albumsAsJs: Album[]) => {
let albums = [];
for (let i = 0; i < albumsAsJs.length; i++) {
albums.push(Album.clone(albumsAsJs[i]));
}
this.albums = albums;
}
Store 像这样传递给组件:(AppView 包含 MasterView)
render() {
return (
<Provider store={new Store()}>
<AppView/>
</Provider>
);
}
我的 package.json 文件
{
"name": "Client_ReactNative2",
"version": "0.0.1",
"private": true,
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/plugin-transform-react-constant-elements": "^7.2.0",
"@babel/plugin-transform-react-inline-elements": "^7.2.0",
"@types/es6-promise": "^3.3.0",
"@types/react": "16.7.6",
"@types/react-native": "0.57.10",
"@babel/core": "^7.0.0-beta.40",
"@babel/cli": "^7.0.0-beta.40",
"babel-loader": "^8.0.0-beta.0",
"babel-plugin-lodash": "^3.3.2",
"babel-plugin-react-transform": "^3.0.0",
"@babel/preset-react": "^7.0.0-beta.40",
"babel-preset-expo": "^5.0.0",
"expo": "31.0.2",
"mobx": "4.8.0",
"mobx-react": "5.2.3",
"react": "16.6.3",
"react-native": "0.57.8",
"react-native-material-ui": "^1.30.1",
"react-native-vector-icons": "^6.1.0"
},
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/preset-flow": "^7.0.0",
"@types/react": "16.7.6",
"@types/react-native": "0.57.10",
"babel-preset-expo": "^5.0.0"
}
}
.babelrc
{
"presets": ["babel-preset-expo"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
预期行为:在 Store.handleAlbumsHaveArrived() 方法调用中设置属性相册后调用的 MasterView.render() 方法。
实际结果:不会发生重新渲染
解决方案
我已经设法通过在 package.json > 依赖项中更改它来使其工作:
"mobx": "4.8.0",
"mobx-react": "5.2.3",
有了这个:
"mobx": "3.2.1",
"mobx-react": "4.2.2",
据我所知,Mobx 易于使用,但有很多错误的版本。
推荐阅读
- google-cloud-functions - 如何使用 Google Cloud Monitoring 监控云功能错误率?
- python - 熊猫到 JSON 文件格式问题,将 \ 添加到字符串
- oauth-2.0 - 如何在 Microsoft Power Automate 中使用自己的 OAuth2 连接自定义 API?
- javascript - 更优雅的加载#container(如谷歌浏览器)
- python - 在代码中使用并使用 Windows
- typescript - 导出你的类不像使用私有构造函数那样严格吗?
- python - Python:检查先前时间戳中是否存在唯一ID,如果存在,则检查之前的时间戳(依此类推)
- discord.py - 试图做一种 pls dep all 或 pls dep max 之类的东西
- php - 试图在 php 中检查上午 9 点以上的时间,但不会在 10 点以上做任何事情?
- javascript - 如何在承诺链中返回一个值?