React Native集成MobX 4配置失败,求调用与变量访问解决方案
Let's walk through fixing your MobX 4 setup for React Native—there are a handful of straightforward issues in your code that are stopping it from working as expected:
Key Issues in Your Current Code
- ProductStore is misstructured: You’re using
extendObservabledirectly without a class context, which breaksthisbinding and proper state management. - Root store instance missing: You’re passing the
Storeclass toProviderinstead of a live instance of the store. - Component not connected to MobX: Your
ProductScreendoesn’t useinjectto access the store orobserverto react to state changes. - Incorrect React Native components: You’re using web-style
<button>instead of React Native’sButtoncomponent, and it’s incorrectly nested inside aTextelement. - Wrong store access path: Even if injected, you’re trying to access
this.props.Storeinstead of the correct nested path (this.props.store.ProductStore).
Fixed Code Files
1. store/ProductStore.js
Refactor into a proper class with MobX observables and actions (MobX 4-friendly):
import { observable, action, runInAction } from "mobx"; export default class ProductStore { constructor(rootStore) { this.rootStore = rootStore; // Keep reference to root store if needed // Initialize observable state observable(this, { products: [], loading: false }); } loadProducts = action(async () => { this.loading = true; try { // Replaced your placeholder API with a working one (JSONPlaceholder) const response = await fetch("https://jsonplaceholder.typicode.com/posts"); const json = await response.json(); runInAction(() => { this.products = json; this.loading = false; }); } catch (error) { runInAction(() => { this.loading = false; }); console.error("Failed to load products:", error); } }); }
2. store/index.js (no changes needed, just confirming)
import { observable } from 'mobx' import ProductStore from './ProductStore' class Store { constructor() { this.ProductStore = new ProductStore(this) } } export default Store
3. App.js (pass a store instance to Provider)
import React from 'react'; import { Provider } from 'mobx-react'; import { StackNavigator } from 'react-navigation'; import Store from './store'; import ProductScreen from './screens/ProductScreen'; const AppNavigator = StackNavigator({ ProductScreen: { screen: ProductScreen } }); // Create a live instance of your root store const rootStore = new Store(); export default class App extends React.Component { render() { return ( <Provider store={rootStore}> <AppNavigator /> </Provider> ); } }
4. screens/ProductScreen.js (connect to MobX and fix UI)
Add inject and observer to connect to the store, plus proper React Native components and state display:
import React from 'react'; import { View, Button, Text, ActivityIndicator, FlatList, StyleSheet } from 'react-native'; import { observer, inject } from "mobx-react"; // Inject root store and make component reactive to state changes @inject('store') @observer class ProductScreen extends React.Component { render() { const { ProductStore } = this.props.store; const { loading, products } = ProductStore; return ( <View style={styles.container}> <Button title="Get Products" onPress={() => ProductStore.loadProducts()} disabled={loading} /> {/* Show loading spinner when fetching */} {loading && <ActivityIndicator style={styles.loader} size="large" />} {/* Show list of products when loaded */} {!loading && products.length > 0 && ( <FlatList data={products} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <View style={styles.productItem}> <Text style={styles.productTitle}>{item.title}</Text> <Text style={styles.productBody}>{item.body.substring(0, 50)}...</Text> </View> )} /> )} {/* Empty state message */} {!loading && products.length === 0 && ( <Text style={styles.emptyText}>No products loaded yet. Tap the button!</Text> )} </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, padding: 16, marginTop: 40 }, loader: { marginVertical: 20 }, productItem: { marginVertical: 8, padding: 12, backgroundColor: '#f0f0f0', borderRadius: 4 }, productTitle: { fontSize: 16, fontWeight: 'bold' }, productBody: { fontSize: 14, color: '#666', marginTop: 4 }, emptyText: { marginTop: 20, textAlign: 'center', color: '#888' } }); export default ProductScreen;
Key Takeaways
- Always pass an instance of your root store to
Provider(not the class itself). - Use
inject('store')to access the root store in components, then destructure child stores likeProductStore. - Decorate components with
@observerso they re-render automatically when MobX observables change. - Structure stores as classes to maintain proper
thiscontext (critical for MobX 4). - Stick to React Native’s native components instead of web HTML elements.
内容的提问来源于stack exchange,提问作者Moni C
相关产品推荐
相关产品推荐

