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

使用componentWillMount/UnMount时遇Provider无法动态修改store错误求助

Hey, let's figure out why you're hitting that Redux Provider error when using those lifecycle methods.

First, let's break down the root causes:

  • You're creating a new Redux Store on every render: Your render method calls createStore(reducers) inside the Provider every time the component re-renders (like when your network state changes). React Redux's Provider doesn't allow swapping out the store dynamically after it's mounted, which triggers that error when lifecycle methods like componentWillUnmount run.
  • Typo in lifecycle method name: You wrote componentWillUnMount (capital M at the end), but the correct name is componentWillUnmount (lowercase m). This means your event listener never gets removed, which can cause memory leaks on top of the store issue.

Here's how to fix it step by step:

Step 1: Create your Redux Store once, outside the component

Instead of making a new store every render, create it once when your app loads. You can do this either outside the App component, or in the constructor so it's only initialized once.

Step 2: Fix the lifecycle method spelling

Make sure componentWillUnmount is spelled correctly so your event listener is properly cleaned up.

Step 3: Clean up the network listener logic

Ensure you're properly removing the listener when the component unmounts, now that the lifecycle method is correctly named.

Here's your updated code with all these fixes:

import React, { Component } from 'react';
import { View, NetInfo, Image } from 'react-native';
import { Container, Text } from 'native-base';
import { RootNavigator } from './src/root';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from './src/reducers/index';

// Create the store ONCE, outside the component
const store = createStore(reducers);

export default class App extends Component {
  constructor(props){
    super(props);
    this.state={
      connection: null,
    };
    // Bind the handler to preserve context
    this.handleConnectionChange = this.handleConnectionChange.bind(this);
  }

  componentWillMount(){
    NetInfo.isConnected.addEventListener("connectionChange", this.handleConnectionChange);
    NetInfo.isConnected.fetch().done((isConnected) => this.setState({connection: isConnected}));
  }

  // Fixed spelling: componentWillUnmount (lowercase m)
  componentWillUnmount(){
    NetInfo.isConnected.removeEventListener("connectionChange", this.handleConnectionChange);
  }

  handleConnectionChange(isConnected){
    this.setState({connection: isConnected});
  }

  handeView(){
    if(this.state.connection !== null && this.state.connection){
      return <RootNavigator />
    } else {
      return (
        <View style={{flex:1, flexDirection:"row", alignItems:"center", justifyContent:"center"}}>
          <Image 
            source={require("./images/connection.gif")} 
            style={{height: 150, width: 150, resizeMode : "stretch"}}
          />
        </View>
      );
    }
  }

  render() {
    return (
      // Use the pre-created store instead of making a new one
      <Provider store={store}>
        <Container>
          {this.handeView()}
        </Container>
      </Provider>
    );
  }
}

Bonus: Notes for future reference

  • If you ever need to update your reducers (like for hot reloading), you can use store.replaceReducer(newReducers) instead of creating a new store. This keeps the same store instance but swaps out the reducer logic, which is allowed.
  • For newer React Native projects, consider using functional components with useEffect instead of class lifecycle methods—it's the recommended approach now, and handles cleanup more intuitively with return functions.

内容的提问来源于stack exchange,提问作者Amir Hossein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:08:55