You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 extendObservable directly without a class context, which breaks this binding and proper state management.
  • Root store instance missing: You’re passing the Store class to Provider instead of a live instance of the store.
  • Component not connected to MobX: Your ProductScreen doesn’t use inject to access the store or observer to react to state changes.
  • Incorrect React Native components: You’re using web-style <button> instead of React Native’s Button component, and it’s incorrectly nested inside a Text element.
  • Wrong store access path: Even if injected, you’re trying to access this.props.Store instead 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 like ProductStore.
  • Decorate components with @observer so they re-render automatically when MobX observables change.
  • Structure stores as classes to maintain proper this context (critical for MobX 4).
  • Stick to React Native’s native components instead of web HTML elements.

内容的提问来源于stack exchange,提问作者Moni C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:18:14