React js检查共享布局中的道具

时间:2018-03-19 15:36:08

标签: javascript reactjs firebase-realtime-database firebase-authentication

我有一个小的React应用程序,它在index.js的应用程序中共享了一个标题组件,其中设置了路由。我想查看特定页面(Admin.js),如果我已登录(Facebook已经使用Firebase完成并且工作正常),如果是这样,请在标题组件上显示注销按钮和Facebook个人资料照片。

index.js(省略导入):

const Root = () => {
  return (
    <div>
      <Header />
      <main>
        <Router>
          <Switch>
            <Route path="/" component={App} exact />
            <Route path="/admin" component={Admin} exact />
          </Switch>
        </Router>
      </main>
    </div>
  );
};


render(<Root/>, document.querySelector('#root'));

Header.js:

import React from 'react';


class Header extends React.Component {
  render() {
    return (
      <header className="header">Header <a href="/">Home</a> 
        <img src={image prop here or something...} alt=""/>
      </header>
    )
  }
}

export default Header

Admin.js

class Admin extends React.Component {

  constructor() {
    super();

    this.addPicture = this.addPicture.bind(this);

    // getinitialstate
    this.state = {
      pictures: [],
            uid: null,
            avatar: ''
    }
  }

  // firebase syncing
  componentWillMount() {
    this.ref = base.syncState('pictures', {
      context: this,
      state: 'pictures',
    });

  }

    componentDidMount() {
        firebase.auth().onAuthStateChanged((user) => {
            if(user) {
                this.authHandler(null, { user });
            }
        })
    }

    authenticate() {
        firebase.auth().signInWithPopup(provider).then(() => {this.authHandler});
    }

    logout = () => {
        firebase.auth().signOut().then(() => {
            this.setState({
                uid: null,
                avatar: ''
            });
        });
    }

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

        this.setState({
            uid: authData.user.uid,
            avatar: authData.user.photoURL
        });
    }

    renderLogin() {
        return (
            <nav>
                <h2>Please log in to access the Admin Area</h2>
                <button className="c-form__btn" onClick={() => this.authenticate()}>Log in</button>
            </nav>
        )
    }

  addPicture(e) {

    e.preventDefault();
    const picsRef = firebase.database().ref('pictures');
    const picture = {
        title: this.title.value,
        url: this.url.value,
        category: this.category.value
        }

    picsRef.push(picture);

    this.picForm.reset();

  }

  removePicture = (key) => {
    const pictures = {...this.state.pictures};
    pictures[key] = null;
    this.setState({ pictures });
  }

  renderTable = () => {
    return Object
      .keys(this.state.pictures)
      .map(key => <Table key={key} index={key} details={this.state.pictures[key]} removePic={() => this.removePicture(key)}/>)
  }


    render() {

        const logout = <button className="c-form__btn secondary" onClick={this.logout}>Log Out!</button>

        // check if ther're no logged id at all
        if(!this.state.uid) {
            return <div>{this.renderLogin()}</div>
        }

        // check if they are the owner of the app
        if(this.state.uid !== USER_UID) {
            return (
                <div>
                    <h3>Access not allowed!</h3>
                    {logout}
                </div>
            )
        }


        return (
      <div>
        <h1>Admin</h1>
                <p>{logout}</p>
                <img src={this.state.avatar} alt="User" style={{width: '50px'}}/>
        <form ref={(input) => this.picForm = input} className="c-form" onSubmit={(e) => this.addPicture(e)}>
          <div className="c-form__field"><input ref={(input) => this.title =input} type="text" placeholder="title" className="c-form__input"/></div>
          <div className="c-form__field"><input ref={(input) => this.url =input} type="text" placeholder="Image url" className="c-form__input"/></div>
                    <div className="c-form__field">
                        <select ref={(input) => this.category =input} className="c-form__input">
                            <option value=" " disabled>Select a category</option>
                            {catOptions()}
                        </select>
                    </div>
          <div className="c-form__field"><button className="c-form__btn" type="submit">Add Item</button></div>
        </form>
        <div className="table">
          <div className="table__row t_header">
            {tableHeader()}
          </div>
          {this.renderTable()}
        </div>
      </div>
        )
    }

}

export default Admin

如何在this.state avatar组件上显示退出按钮和Facebook个人资料照片(Header)?

1 个答案:

答案 0 :(得分:0)

您需要lift the state up。对于示例

class Root extends React.Component {
  state = { 
    isLogged: false
    img: null,
    username: '',
  }

  login = (username, img) => {
    this.setState({
      img,
      username,
      isLogged: true,
    });
  }

  logout = () => {
    this.setState({
      img: null,
      username: '',
      isLogged: false,
    })
  }    

  render() {
    return (
      <div>
        <Header 
          username={this.state.username}
          img={this.state.img} 
          isLogged={this.state.isLogged} 
          logout={this.logout} 
        />
        <main>
          <Router>
            <Switch>
              <Route path="/" component={App} exact />
              <Route 
                exact 
                path="/admin" 
                render={props => <Admin {...props} login={this.login} />} 
              />
            </Switch>
          </Router>
        </main>
      </div>
    );
  }
};

现在,您可以使用传递给Root的更新程序功能更新Admin中的状态。从现在开始,你只需将道具传递给你想要的任何东西。你明白了......