首页 > 解决方案 > How to pass the username into multi pages in reactjs

问题描述

I'm totally new to reactjs. I have successfully created user register tab and login tab also. problem is after login; the username should be show into the nav bar. As my site I have created nav bar page(NavBar.js) and login page (Login.js) separately As my learn sessionStorage and props can possible for this. but I'm totally confused how to use it. please anyone give hint to solve my problem. my backend is loopback This is my login.js

const FormItem = Form.Item;

    export default class Login extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          email: "",
          password: "",
          details: ""
        };
      }

      handleChange = event => {
        this.setState({ [event.target.name]: event.target.value });
      };

      onSubmit(e) {
        var email = this.state.email;
        var password = this.state.password;
        axios
          .get(
            `http://localhost:3000/api/UserLogins/findOne?filter={"where":{"email":"${email}"}}`
          )
          .then(response => {
            this.setState({ details: response.data }, () => {
              if (password === this.state.details.password) {
                console.log("login");
              } else {
                console.log("not login");
              }
            });
          })
          .catch(err => console.log(err));
        e.preventDefault();
      }

      render() {
        let UserLoginDetail = this.state.details.username;
        sessionStorage.setItem(UserLoginDetail, this.state.details.username);

        return (
          <div>
            <form onSubmit={this.onSubmit.bind(this)}>
              <FormItem>
                <Input
                  onChange={this.handleChange}
                  prefix={<Icon type="mail" style={{ color: "rgba(0,0,0,.25)" }} />}
                  name="email"
                  type="email"
                  placeholder="abcd@gmail.com"
                />
              </FormItem>
              <FormItem>
                <Input
                  onChange={this.handleChange}
                  prefix={<Icon type="lock" style={{ color: "rgba(0,0,0,.25)" }} />}
                  name="password"
                  type="password"
                  placeholder="Password"
                />
              </FormItem>
              <FormItem>
                <Checkbox>Remember me</Checkbox>
                <a className="login-form-forgot" href="">
                  Forgot password
                </a>
                <Button
                  type="primary"
                  htmlType="submit"
                  className="login-form-button"
                >
                  Log in
                </Button>
              </FormItem>
            </form>
          </div>
        );
      }
    }

NavBar.js code is

import React from 'react';
import 'antd/dist/antd.css';
import 'bootstrap/dist/css/bootstrap.css';
import { Collapse,Navbar,NavbarToggler,NavbarBrand,Nav,NavItem,NavLink} from 'reactstrap';
import ResizeImage from 'react-resize-image';
import { Row, Col } from 'antd';
import { Modal, Button } from 'antd';
import { Tabs,Icon } from 'antd';
import Login from './Login';
import Register from './Register';

const TabPane = Tabs.TabPane;

function callback(key) {
  console.log(key);
}

export default class NavBar extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      isOpen: false,
    };
  }
  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  state = { visible: false }

  showModal = () => {
    this.setState({
      visible: true,
    });
  }

  handleOk = (e) => {
    console.log(e);
    this.setState({
      visible: false,
    });
  }

  handleCancel = (e) => {
    console.log(e);
    this.setState({
      visible: false,
    });
  }

  render() {
    let myItem = sessionStorage.getItem('userName');
    return (
      <Row className="vert-align">
      <Col push={24}>
      <div>
        <Navbar color="light" white="true" expand="md">
          <NavbarBrand href="/">
          <ResizeImage
            src={require('../image/logo.png')}
            alt="logo"

          />
      </NavbarBrand>
        <NavbarToggler onClick={this.toggle} />
          <Collapse isOpen={this.state.isOpen} navbar>
            <Nav className="ml-auto" navbar>
              <NavItem>
                <NavLink href="/">Home</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="/Car">All Cars</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="/Rate">Rates</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="/About">About Us</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="/BecomePartner"><Icon type="team" />  Become a Partner</NavLink>
              </NavItem>
              <p>{myItem}</p>
              <div>
                <Button type="default" onClick={this.showModal}>
                  <Icon type="login" />Login
                </Button>

                <Modal
                  visible={this.state.visible}
                  onCancel={this.handleCancel}
                  onOk={this.handleOk}
                >
                  <Tabs defaultActiveKey="1" onChange={callback}>
                    <TabPane tab="Login" key="1"><Login/>
                    </TabPane>
                    <TabPane tab="Register" key="2"><Register/></TabPane>
                  </Tabs>
                </Modal>

              </div>

            </Nav>
          </Collapse>
        </Navbar> 
      </div>
      </Col >
      </Row >
    );
  }
}

标签: reactjsloopback

解决方案


在登录文件中以这种方式使用 SessionStorage:-

sessionStorage.setItem('UserName', this.state.details.username);

在当前代码中,您使用 key 作为 this.state.details.username 和 value 作为 this.state.details.username。

Key 应该始终是固定的,它不应该依赖于用户输入,以便您可以使用它来获取值。

导航栏代码共享后:-

这段代码应该放在里面

 axios
 .get(
  `http://localhost:3000/api/UserLogins/findOne?filter={"where":{"email":"${email}"}}`
          )
     .then(response => {
      this.setState({ details: response.data }, () => {
       if (password === this.state.details.password) {
        console.log("login");
        sessionStorage.setItem('UserName', this.state.details.username);
        this.props.handeLogin(); 
        /*It will change state of NavBar 
         Component,and it would be re-rendered.
         So,we will get new User Name from 
         session.*/

       } else {
          console.log("not login");
          }
        });
          })

Session值应该在这个axios调用里面设置,因为这里的值是变化的,不应该在render方法中赋值,因为每次状态变化都会调用render方法。

在导航文件中获取用户名:- sessionStorage.getItem('userName');

在 Navfile 添加状态属性 isLoggedIn,

 this.state = {
      isOpen: false,
      isLoggedIn:false
    };

然后添加方法 handlelogin() :-

handleLogin=()=>{
   this.setState({
      isLoggedIn:true
    })
}.

我们遵循更改状态的过程,因为即使 SessionStorage 用户名发生更改,导航组件也不会重新渲染。

如果其他组件中需要用户名,则可以使用以下方式获取它:- sessionStorage.getItem('userName');

如果您计划Redux用于状态管理,请访问:- https://redux.js.org/

Redux 基于 .Single Source of Truth它就像一个组件,例如,Login 将使用新的 userName 更新 redux 存储,而 NavBar 组件将获取更新后的 userName,因为它会订阅存储。

希望这可以帮助,

干杯!!


推荐阅读