繁体   English   中英

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

[英]How to pass data to a component from sibling component react

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

我有一个header组件,其中有一个名为Adminnav ,如果admin登录,则必须可见。

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

我的要求类似于React:如何将道具从孩子传递给父母,再传递给另一个孩子? 但我的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);

标头组件

import React, { Component } from 'react';
import {
    Collapse,
    Navbar,
    NavbarToggler,
    Nav,
    NavItem,
    NavLink
} from 'reactstrap'; 
import './header.css';
import HeaderCollapse from './header-collapse/header-collapse';
import logo from '../../assets/logo.png';
import usericon from '../../assets/user.png';
import { ListGroup, ListGroupItem } from 'reactstrap';
import { Link } from 'react-router-dom';

class HeaderComponent extends Component {

    headerList = [
                  {'Id':1,'Title':'K-12 Physics','submenu':['Video Lectures & Practice','White Papers','Revision Tree & Learning curve']},
                  {'Id':2,'Title':'Scinema','submenu':['Story of science','Modern Science','Learn Science']},
                  {'Id':3,'Title':'WorkShops','submenu':['Argon','Neon','Xenon']},
                //   {'Id':4,'Title':'Ed-Tech','submenu':['Item1','Item2','Item3']} // future sprint
                ];

    constructor(props) {
        super(props);

        this.state = {
            isOpen: false,
            activeItem: -1,
            showCollapseBar: false,
            showUserAction: false,
            isAuthUser:false,
            selData:[]
        };
        this.toggle = this.toggle.bind(this);
        this.hideCollapse = this.hideCollapse.bind(this);
        this.showActionModel = this.showActionModel.bind(this);
        this.setWrapperRef = this.setWrapperRef.bind(this);
        this.handleClickOutside = this.handleClickOutside.bind(this);
        this.logout = this.logout.bind(this);
        this.updateState = this.updateState.bind(this);
        this.onclickOutsideHeaderContainer = this.onclickOutsideHeaderContainer.bind(this);
        this.handleItemClick = this.handleItemClick.bind(this);
        this.collapseCallback = this.collapseCallback.bind(this);
        this.setheaderContainerRef = this.setheaderContainerRef.bind(this);
        console.log('header props',this.props)
    }

    componentDidMount() {
        console.log('header component testing', localStorage.getItem('isUserLoggedIn'))
        document.addEventListener('mousedown', this.handleClickOutside);
        console.log('Logged in user details',localStorage.getItem('authUser'))
        this.updateState();

      }
      updateState(){
          console.log('update state triggered from header compoenet')
        this.setState({isAuthUser: localStorage.getItem('isUserLoggedIn')});
        console.log(localStorage.getItem('authUser'))
      }

    //   showAdminNav(){
    //     console.log('show admin nav triggered')
    //   }

    onSignIn(){
        console.log('On Sign in Method call')
    }

      handleClickOutside(event) {
        if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
            this.setState({
                showUserAction: !this.state.showUserAction
            });
        }
        if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
            // some code..
            //alert('mobile biew')
            if(event.path[0].className !== 'actionLink.nav-link'){
                return;
            }
                //this.hideCollapse();
           }
      }

      onclickOutsideHeaderContainer(event){
        if(!this.headerContainerRef.contains(event.target))
            this.hideCollapse()
      }
    handleItemClick(index,data) {
        console.log(data)
        this.setState({
            activeItem: index,
            showCollapseBar: true,
            selData:data
        })

    }


    toggle() {        
        this.setState({
            isOpen: !this.state.isOpen,
            //showCollapseBar: !this.state.showCollapseBar /**Commented to fix toggle */
        });
        this.hideCollapse();
    }

    hideCollapse(){
        this.setState({
            showCollapseBar: false
        });
    }

    collapseCallback = (data) => {
        if (data === 'hide Collapse') {
            this.setState({
                activeItem: -1,
                showCollapseBar: false
            })
        }
    }
    showActionModel(){         
        this.setState({
            showUserAction: !this.state.showUserAction
        });

    }
    setWrapperRef(node) {
        this.wrapperRef = node;
      }

      setheaderContainerRef(node){
          this.headerContainerElement = node;
      }

      logout(){
        console.log('logout method triggered')
        localStorage.setItem('authUser',null);
        localStorage.setItem('isUserLoggedIn',false);
        this.props.history.push('/');
      }

    render() {
        const showCollapseBar = this.state.showCollapseBar;
        const showActionModel = this.state.showUserAction;
        const isUserLoggedIn = this.state.isAuthUser === "true" ? true : false;

        let collapseBar = "null";
        if (showCollapseBar) {
            collapseBar = <HeaderCollapse data = {this.state.selData} callbackFromheader={this.collapseCallback}/>;
        } else {
            collapseBar = null;
        }

        const headerList = this.headerList.map((header, index) =>
            <NavItem key={header.Id.toString()} className={this.state.activeItem === index ? 'active' : ''}>
                <NavLink onClick={this.handleItemClick.bind(this, index,header)}>
                    {header.Title}
                </NavLink>
            </NavItem>

        );

        let actionList = null;
        if(isUserLoggedIn){
            actionList = <ListGroup>
                <ListGroupItem>Profile</ListGroupItem>
                <ListGroupItem onClick={this.logout}>Logout</ListGroupItem>            
            </ListGroup>;
        }else{
            actionList = <ListGroup>            
            <ListGroupItem><Link className="actionLink nav-link" to="/signin">Sign In</Link></ListGroupItem>
            <ListGroupItem><Link className="actionLink nav-link" to="/SignUp">Not a member yet.? Sign Up Now</Link></ListGroupItem>
            </ListGroup>;
        }

        //<img src={logo} height="60"/>
        return (
            <div className="header-container" id="header-container" >
                <Navbar color="light" light expand="md" dark >                  
                        <Link to="/"><img src={logo} height="60"/></Link>                    
                    <NavbarToggler onClick={this.toggle} />
                    <Collapse isOpen={this.state.isOpen} navbar>
                        <Nav className="ml-auto" navbar>
                            {headerList}
                            <NavItem>                                                         
                                   <Link to="/contacts" onClick={this.hideCollapse} className="actionLink nav-link">Contact</Link>                                  
                            </NavItem>

                            <NavItem>                                
                                <Link className="actionLink nav-link" to="/managedata">Admin</Link>                            
                            </NavItem>
                            <NavItem>                                
                                {/* <Link className="actionLink nav-link" to=""> */}
                                    <img id="user-icon" src={usericon} onClick={this.showActionModel}/>
                                {/* </Link>                             */}
                            </NavItem>

                        </Nav>

                    </Collapse>
                </Navbar>
                {showActionModel && <div id="user-actions" ref={this.setWrapperRef}>
                    {actionList}
                </div>}
                {collapseBar}


            </div>


        );
    }
}

export default HeaderComponent;

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

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

onSignIn() {
 this.updateState()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM