如何让不相关的组件影响主App状态?

时间:2017-04-30 18:42:45

标签: javascript reactjs

我在<Navbar />组件的渲染顶部有一个<App />组件,在Navbar中有一个指向某个登录页面的链接,这是由路由器处理的。如果我不能像<Login loginHandler={this.loginHandler} />那样以传统方式传递状态,那么如何从Login.js中所做的更改中提升状态?

有人告诉我,我应该将这些功能抽象为一个单独的模块,并在两个组件之间共享它,但是我太过于反应初学者,我需要一些例子。

由于

以下是回购:https://github.com/charlesdarkwind/vitae-eternam

添加了组件:

基本上登录方法是authHandler和authenticate,现在它只是设置用户ID(uid)的状态我希望是全局的

App.js:

import React from 'react'; 
import NavbarTop from './NavbarTop';

class App extends React.Component {
  constructor() {
    super();       
    this.authenticate = this.authenticate.bind(this);
    this.authHandler = this.authHandler.bind(this); 
  }

  state = {
    items: {},
    order: {},
    uid: null
  };  

  render() {
    return (
      <div>
        <NavbarTop />
      </div>          
    );
  }
}

export default App;

Login.js:

import React from 'react';
import { Button } from 'react-bootstrap';
import base from '../base';
import NavbarTop from './NavbarTop';

class Login extends React.Component {
    componentDidMount() {
        base.onAuth((user) => {
            if(user) {
                this.authHandler(null, { user });
            }
        });
    }

authenticate(provider) {
    console.log(`Tentative de connexion avec ${provider}`);
    base.authWithOAuthPopup(provider, this.authHandler);
  }

  authHandler(err, authData) {
    console.log(err, authData);
    if(err) {
      console.error(err);
      return; 
    }

    // grab the cart/order info
    const orderRef = base.database().ref(this.props.uid); //NEED SOME ID REFERING TO CURRENT ORDER CART

    // query the firebase ref once for the cart data and set the state
    orderRef.once('value', (snapshot) => {
      const data = snapshot.val()  || {};
      this.setState({
        uid: authData.user.uid
      });
    });   
  }

    render() {
        return (
            <div>
                <NavbarTop />
                <div className="loginWrap">
                    <nav className="login">
                        <p>Connexion</p>
                        <Button bsStyle="primary" className="facebook" onClick={() => this.props.authenticate('facebook')}>Connexion avec FaceBook</Button>
                        <Button bsStyle="danger" className="google" onClick={() => this.props.authenticate('google')}>Connexion avec Google</Button>
                </nav>              
                </div>
            </div>
        )
    }
}

export default Login;

1 个答案:

答案 0 :(得分:1)

如果您在没有任何状态管理库的情况下使用react,那么props就是传递数据的唯一方法。实际上,为了更准确,它是传递数据的唯一正确方式,从技术上讲,您可以通过将数据附加到window对象以使其成为全局或通过使用localStorage。我会远离窗口对象,但localStorage是一个可行的选择。

话虽如此,您应该开始研究状态管理库,例如reduxMobX。他们出于这个原因使用它们,为您提供了更好的方法来实现跨组件的持久数据和数据可访问性。

如果您只需要跟踪用户是否已登录,那么您可以使用localStorage,但如果您开始遇到与应用程序其他部分相同的问题,并且需要使用越来越多的数据/ global然后你应该使用状态管理库。