将this.state带到外部范围

时间:2018-05-29 10:44:08

标签: javascript reactjs

这是我的App.js

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import {BrowserRouter as Router} from 'react-router-dom';
import Navbar from "./components/nav";
import firebase from './firebase';
import Questions from './components/questions';
import Stuff from './components/stuff';
class App extends Component {
    constructor(p) {
        super(p);
        this.state = {user: null}
    }

    render() {
        return (
            <div className="App">
                <Navbar/>
                {this.state.user ? <Questions/> : <Stuff/>}
            </div>
        );
    }
}

export default App;

这个想法是,它应该渲染导航栏,如果用户登录,它应该渲染Questions元素,否则,渲染其他东西。

这是我的<Navbar/>元素:

import React from 'react';
import {Navbar as Bar, Nav, NavItem, Modal, Button, FormControl} from 'react-bootstrap';
import {BrowserRouter as Router, Link, Route} from 'react-router-dom';
import firebase, {auth} from '../firebase';

class Navbar extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
        this.login = this.login.bind(this);
        this.logout = this.logout.bind(this);
        this.openLogin = this.openLogin.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }

    componentDidMount() {
        auth.onAuthStateChanged((user) => {
            if (user) {
                this.setState({user});
            }
        });
    }

    logout() {
        auth.signOut()
            .then(() => {
                this.setState({
                    user: null
                });
            });
    }

    login() {
        var email = document.getElementById('email').value;
        var password = document.getElementById('password').value;
        auth.signInWithEmailAndPassword(email, password)
            .then(result => {
                    const user = result.user;
                    this.setState({user});
                    document.getElementById('close').click();
                }
            ).catch(e => console.log(e));
    }

    openLogin() {
        this.setState({show: true});
    }

    handleClose() {
        this.setState({show: false});
    }

    render() {
        return (
            <React.Fragment>
                <Router>
                    <Bar>
                        <Bar.Header>
                            <Bar.Brand>
                                <a href="/home">UczIchApp</a>
                                {/*<Route path='path' component=""/>*/}
                            </Bar.Brand>
                            <Bar.Brand>

                            </Bar.Brand>
                        </Bar.Header>
                        <Nav>
                            {
                                this.state.user ?
                                    <NavItem onClick={this.logout}>Wyloguj się</NavItem>
                                    :
                                    <NavItem onClick={this.openLogin}>Zaloguj się</NavItem>
                            }
                        </Nav>
                    </Bar>
                </Router>
                <Modal show={this.state.show} onHide={this.handleClose}>
                    <Modal.Header closeButton>
                        <Modal.Title>Modal heading</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                        <form>
                            <FormControl
                                id="email"
                                type="email"
                                label="Email address"
                                placeholder="Enter email"
                            />
                            <FormControl id="password" label="Password" type="password"/>
                            <Button onClick={this.login}>Zaloguj</Button>
                        </form>
                    </Modal.Body>
                    <Modal.Footer>
                        <Button id="close" onClick={this.handleClose}>Close</Button>
                    </Modal.Footer>
                </Modal>
            </React.Fragment>
        )
    }
}

export default Navbar;

所以我想根据<App/>元素中更改的用户状态更改<Navbar/>元素中的内部。我怎样才能做到这一点?现在状态在<App.js/>

中不可用

2 个答案:

答案 0 :(得分:1)

在App Component中创建一个函数checkUserState

 constructor(p) {
    super(p);
    this.state = {user: null}
    this.checkUserState= this.checkUserState.bind(this);
}

checkUserState(user){
    this.seState({user});
}

然后将Navbar组件中的props传递为

 <Navbar {...this}/>

在您设置状态的Navbar Component内部,执行此操作

this.setState({
        user: null
    },function(){
        this.props.checkUserState(this.state.user)
    });

由于Navbar是子组件,因此您需要反转。

答案 1 :(得分:0)

看起来你需要全局处理应用程序的状态。您可以尝试使用redux来管理该应用的状态。或者您可以将一个函数作为prop从您的父组件传递给导航器,该函数可以处理状态

Js fiddle example

const Nav = ({ handleClick }) => {
    return (<button onClick={handleClick}>hello world</button>);
}

class HelloMessage extends React.Component {
    constructor(props){
    super(props);
    this.state = {
    checked: false
    }
  }
    handleClick = (e) => {
    e.preventDefault();
        this.setState({checked: !this.state.checked});
  }
  render() {
    return (
      <div>
      <Nav handleClick={this.handleClick}/>
      <p><b>status:</b> {this.state.checked ? 'checked' : 'unchecked'}</p>
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  document.getElementById('app')
);