如何将数据从同级组件传递到组件

时间:2018-12-26 13:09:54

标签: javascript reactjs

我的要求是根据已登录的用户重新呈现标头组件。

我有一个header组件,其中有一个名为nav的{​​{1}},如果管理员登录,该组件必须可见。

我还有一个其他组件调用Admin组件,在其中,当管理员登录时,我需要将该值传递给signin组件,以便显示管理员导航。

我的要求类似于React: how to pass props from child to parent to another child? 但我的header组件在路由器中。

成功登录后,我会将用户路由到主页并在本地存储中设置值,但我的标题组件未重新呈现。

有什么办法可以做到这一点?

请帮助。

应用组件

signin

登录组件

import React, { Component } from 'react';
import '../node_modules/video-react/styles/scss/video-react.scss';
import '../node_modules/bootstrap-vertical-tabs/bootstrap.vertical-tabs.min.css';
import routes from './routes';
import {withRouter} from 'react-router-dom';
import HeaderComponent from './components/header-component/header';
import './App.css';
import Footer from './components/footer/Footer';
import loader from './assets/loader.png';
import { Animated } from 'react-animated-css';
import firebase from "firebase";


class App extends Component {

  constructor(props){
    super(props);
    this.props = props;
    this.state = {
      authUser:null
    }
    this.handleSignInHeader = this.handleSignInHeader.bind(this);
  }

  onSignIn(data){
    console.log(data);
  }
  componentDidMount(){
    firebase.auth().onAuthStateChanged(authUser =>{
      authUser ? this.setState(() => ({ authUser })) : this.setState(() => ({ authUser: null }));
    })
    console.log(this.state)
  }

  handleSignInHeader(){
    console.log('Sign handleSignInHeader method triggered')
  }

  render() {

    return (
      <div className="App" >
      <div className="logo-wrapper ">
      <div className="image-wrapper">
      <Animated animationIn="bounce infinite" >
        <img alt="loader" src={loader}/>
      </Animated>
      </div>


        </div>
      <div className="container-fluid">
      <div className="row set-min-height"><HeaderComponent/></div>  
      <div className="row route-container" >      
          {routes}      
      </div> 
      <div className="row">
      <Footer/>
      </div>              
      </div>
      </div>

    );
  }
}

export default App;

标题组件

import React, { Component } from 'react';
import './sign-in.css';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { auth } from '../../firebase/index';
import { Link } from 'react-router-dom';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import TextField from '@material-ui/core/TextField';
import { withSnackbar } from 'notistack';
import firebase from "firebase";



const INITIAL_STATE = {
    email: '',
    password: '',
    error: null,
    openDialog: false,
    resetEmail:''
  };

  const byPropKey = (propertyName, value) => () => ({
    [propertyName]: value,
  });


    class Signin extends Component{
        constructor(props) {
            super(props);
            this.resetPassword = this.resetPassword.bind(this);
            this.handleCancel = this.handleCancel.bind(this);
            this.handleReset = this.handleReset.bind(this);        
            this.state = { ...INITIAL_STATE };
          }
          resetPassword(){
            console.log('reset password clicked');
            this.setState({
              openDialog: true 
            })
          }
          handleCancel(){
          this.setState({
            openDialog: false 
          })
        }

          handleReset(){
            const { enqueueSnackbar } = this.props; 
            console.log(this.state)
            let auth = firebase.auth();
            this.setState({
              openDialog: false 
            })
            auth.sendPasswordResetEmail(this.state.resetEmail).then(function() {
              // Email sent.
              enqueueSnackbar('Email sent successfully');          
            }).catch(function(error) {
              // An error happened.
              let err= error.message
              enqueueSnackbar(err);
            });
          }
          onSubmit = (event) => {
            const { enqueueSnackbar } = this.props;
            console.log('value of props on submit logged',this.props)
            const {
              email,
              password,
            } = this.state;    
            auth.doSignInWithEmailAndPassword(email, password)
              .then(() => {
                this.setState({ ...INITIAL_STATE });          
                enqueueSnackbar('sign in succesfull');
                console.log(firebase.auth().currentUser);
                let authUser = firebase.auth().currentUser;
                console.log(authUser);
                localStorage.setItem('authUser',JSON.stringify(authUser));
                localStorage.setItem('isUserLoggedIn',true);
                this.props.onSignIn('sign in Successfull');
                this.props.history.push('/');//routing to landing page
              })
              .catch(error => {
                this.setState(byPropKey('error', error));
                console.log(error)
              });

            event.preventDefault();
          }

        render(){
            const {
                email,
                password            
              } = this.state;
            return(
                <div className="login-body">
                <div className="hybrid-login-form">
                    <div className="sign-in-content">
                    <h1>Sign In</h1>
                    <Form onSubmit={this.onSubmit}>
                        <FormGroup>
                        <Label className="set-label-pos" for="Email">Email</Label>
                        <input value={email} className="form-control" onChange={event => this.setState(byPropKey('email', event.target.value))}
              type="text" placeholder="Email" />
                        </FormGroup>
                        <FormGroup>
                        <Label className="set-label-pos" for="Password">Password</Label>
                        <input className="form-control" value={password} onChange={event => this.setState(byPropKey('password', event.target.value))}
              type="password" placeholder="Password" />

                    </FormGroup>
                    <Button className="btn btn-danger sign-in-btn" size="lg" type="submit">Sign In</Button>
                    <FormGroup check className="remember-me">
                                <Label className="set-label-pos" check>
                                <Input type="checkbox" />{' '}   Remember me</Label>
                                <Label className="set-frgt-pass" onClick={this.resetPassword}>Forgot Password</Label>
                    </FormGroup>

                    </Form>
                    </div>
                    <div className="signup-content">
                        New to Faraday? <Link to="/signup">Sign up now.</Link>                    
                    </div>
                </div>

                <Dialog  open={this.state.openDialog}  onClose={this.handleClose} aria-labelledby="alert-dialog-title"   aria-describedby="alert-dialog-description">
                        <DialogTitle id="alert-dialog-title">{"Reset Password"}</DialogTitle>
                        <DialogContent>
                            <DialogContentText id="alert-dialog-description">
                              Please enter your registered email address, an email will be sent for resetting password.
                            </DialogContentText>
                        </DialogContent>
                        <TextField
                            autoFocus
                            margin="dense"
                            id="name"
                            label="Email Address"
                            type="email"
                            onChange={event => this.setState(byPropKey('resetEmail', event.target.value))}                   
                          />
                        <DialogActions>
                            <Button onClick={this.handleCancel} color="primary">
                               Cancel
                            </Button>
                            <Button onClick={this.handleReset} color="primary" autoFocus>
                            Reset
                            </Button>
                        </DialogActions>
                        </Dialog>
                </div>

            )
        }

    }

    export default withSnackbar(Signin);

2 个答案:

答案 0 :(得分:0)

渲染组件时,

componentDidMount仅被调用一次。因此,请确保每次登录或注销时都调用函数updateState。

答案 1 :(得分:0)

如果我正确理解代码,我认为在updateState中调用onSignIn方法应该可以解决问题。

onSignIn() {
 this.updateState()
}