【问题标题】:React/Redux dispatch action from root component?来自根组件的 React/Redux 调度操作?
【发布时间】:2017-04-03 15:29:43
【问题描述】:

我正在尝试将 firebase 与 React-Native / Redux 一起使用,我需要在每次用户登录或注销时调度一个操作。如何从根组件调度操作?

class App extends Component {
    componentWillMount() {
        firebase.auth().onAuthStateChanged((user) => {
            if (user) {
            // Dispatch Action here
            } else {
            // Disptach Action here
            }
        });
    }

    render() {
        const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));

        return (
            <Provider store={store}>
                <Router />
            </Provider>
        );
    }
}

export default App;

【问题讨论】:

    标签: reactjs firebase react-native redux firebase-authentication


    【解决方案1】:

    我找到了解决这个问题的方法。不应该是最好的方法,但它确实有效。

    在根组件 (App.js) 上将身份验证请求设置为 true 或 false。 (我在下面的示例中使用 firebase 身份验证)

    完成后,您将状态作为道具传递给组件 (InitialSetUp.js),然后您可以使用 Redux 设置状态。

    在 InitialSetUp 上,您像根一样渲染应用程序本身。

    您可以在下面找到示例。

    App.js

    ...
    
    const store = createStore(reducers, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && 
    window.__REDUX_DEVTOOLS_EXTENSION__());
    
    export default class App extends Component {
    state = { loggedIn: null};
    
    componentWillMount() {
    firebase.initializeApp({
    ...YOUR SETUP
    });
    
    firebase.auth().onAuthStateChanged((user) => {
    if (user) {
    this.setState({ loggedIn: true});
    } else {
    this.setState({ loggedIn: false});
    }
    });
    }
    
    renderInitialView() {
    return  <InitialSetUp loggedIn={this.state.loggedIn}/>
    }
    
    render() {
    return (
    <Provider store={store}>
    <View style={styles.container}>
    {this.renderInitialView()}
    </View>
    </Provider>
    );
    }
    }
    

    InitialSetup.js

    ...
    
    class initialSetUp extends Component {
    
    renderInitialView() {
    this.props.setLogged(this.props.loggedIn);
    return  <Navigation />
    }
    
    render() {
    return (
    <View style={styles.container}>
    {this.renderInitialView()}
    </View>
    );
    }
    }
    
    export default connect(null, actions)(initialSetUp);
    

    祝你好运哦/

    【讨论】:

      【解决方案2】:
      class App extends Component {
          constructor() {
              this.store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
          }
      
          componentWillMount() {
              firebase.auth().onAuthStateChanged((user) => {
                  if (user) {
                      this.store.dispatch(...);
                  } else {
                      this.store.dispatch(...);
                  }
              });
          }
      
          render() {
              return (
                  <Provider store={this.store}>
                      <Router />
                  </Provider>
              );
          }
      }
      
      export default App;
      

      并且不要在render() 函数中产生任何副作用。它必须是纯函数。

      【讨论】:

      • 最好不要在组件构造函数中创建 store,而只使用 React-Redux 中的 Provider。在组件内部创建 store 不是 Redux 方式。
      • @DDS 这是主要的应用程序组件,因此在构造函数或外部组件中初始化存储没有区别。
      【解决方案3】:

      使用 redux connectmapDispatchToProps... 找到文档 here。 Connect 仍将与根组件一起使用。然后在您的componentWillMount 中,您可以引用通过connect 传递给它的组件道具中的操作

      【讨论】:

      • 我已经尝试过了,它不起作用我收到以下错误“在“Connect(App)”的上下文或道具中找不到“存储”。要么将根组件包装在,或显式将“store”作为道具传递给“Connect(App)”
      • 将提供程序移动为静态并将您的身份验证内容放在使用连接的父组件上。
      • 我在使用 react-native-router-flux 时遇到了同样的错误,这可能与它有关吗?
      猜你喜欢
      • 2016-06-06
      • 2017-07-08
      • 2017-08-15
      • 2021-04-16
      • 1970-01-01
      • 2017-11-09
      • 2020-08-18
      • 1970-01-01
      • 2019-10-23
      相关资源
      最近更新 更多