繁体   English   中英

如何在 ReactJS 中的 2 个类之间传递数据

[英]How to pass data between 2 classes in ReactJS

我对我认为是学校作业的反应钩子有疑问。

在我的 app.js 中,我使用条件渲染来渲染 2 个不同的导航栏:1 个用于普通用户,1 个用于管理员。 我无法理解如何从 login.js 更改呈现导航栏的 app.js 状态。 下面是我的代码。

登录.js

  handleLogon(){
    try{
      if(this.username == "user1" && this.password == "pass123"){
        //send info to app.js
      }
    }
    catch{
      this.setState({
        message: "Incorrect Credentials"
      });
    }
  }

应用程序.js

  //create state for loggedin 
  constructor(props) {
    super(props);

    this.state = {
      isLoggedIn: false
    }
  }

  handleLogonChange(b) {
    if(b) {
      this.setState({
        isLoggedIn: true
      });
    }
  }

App.js 渲染

render() {
    if (this.state.isLoggedIn) {
      return (
        <div>
          <nav className="navbar navbar-expand navbar-dark bg-dark">
            <a href="/menus" className="navbar-brand">
              Blue Devil Cafe Online
          </a>
            <div className="navbar-nav mr-auto">
              <li className="nav-item">
                <Link to={"/menus"} className="nav-link">
                  Menus
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/addmenu"} className="nav-link">
                  Add Menu
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/menuitems"} className="nav-link">
                  Menu Items
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/addmenuitem"} className="nav-link">
                  Add Menu Item
              </Link>
              </li>
            </div>
          </nav>

          <div className="container mt-3">
            <Switch>
              <Route exact path={["/", "/menuitems"]} component={MenuItemList} />
              <Route exact path="/addmenuitem" component={AddMenuItem} />
              <Route path="/menuitems/:id" component={MenuItem} />

              <Route exact path={"/menus"} component={MenuList} />
              <Route exact path="/addmenu" component={AddMenu} />
              <Route path="/menus/:id" component={Menu} />
            </Switch>
          </div>

        </div>
      )
    }
    else {
      return (
        <div>
          <nav className="navbar navbar-expand navbar-dark bg-dark">
            <a href="/menus" className="navbar-brand">
              Blue Devil Cafe Online
          </a>
            <div className="navbar-nav mr-auto">
              <li className="nav-item">
                <Link to={"/home"} className="nav-link">
                  Home
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/calendar"} className="nav-link">
                  Calendar
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/cart"} className="nav-link">
                  Cart
              </Link>
              </li>
              <li className="nav-item">
                <Link to={"/login"} className="nav-link">
                  Login
              </Link>
              </li>
            </div>
          </nav>

          <div className="container mt-3">
            <Switch>
              <Route exact path={"/home"} component={Home} />
              <Route exact path={"/calendar"} component={Calendar} />
              <Route exact path={"/cart"} component={Cart} />
              <Route exact path={"/login"} component={Login} />
            </Switch>
          </div>

        </div>
      )
    }
  }

我想从登录发送的是一个真正的布尔值到应用程序,以便它可以呈现更改条件以呈现管理员的导航栏而不是一般用户的导航栏。 如果您还有什么需要,请告诉我们。

尝试在 Route 上使用 render 方法而不是组件。 这样,您可以将该函数作为道具引用传递给 Login 并从 child 获取值以更新 parent。

这是代码:

//create state for loggedin 
 constructor(props) {
  super(props);

  this.state = {
    isLoggedIn: false
  }
}

handleLogonChange(b) 
{
  if(b) {
    this.setState({
      isLoggedIn: true
    });
  }
}

render() {
  if (this.state.isLoggedIn) {
    return (
      <div>
        <nav className="navbar navbar-expand navbar-dark bg-dark">
          <a href="/menus" className="navbar-brand">
            Blue Devil Cafe Online
        </a>
          <div className="navbar-nav mr-auto">
            <li className="nav-item">
              <Link to={"/menus"} className="nav-link">
                Menus
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/addmenu"} className="nav-link">
                Add Menu
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/menuitems"} className="nav-link">
                Menu Items
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/addmenuitem"} className="nav-link">
                Add Menu Item
            </Link>
            </li>
          </div>
        </nav>

        <div className="container mt-3">
          <Switch>
            <Route exact path={["/", "/menuitems"]} component={MenuItemList} />
            <Route exact path="/addmenuitem" component={AddMenuItem} />
            <Route path="/menuitems/:id" component={MenuItem} />

            <Route exact path={"/menus"} component={MenuList} />
            <Route exact path="/addmenu" component={AddMenu} />
            <Route path="/menus/:id" component={Menu} />
          </Switch>
        </div>

      </div>
    )
  }
  else {
    return (
      <div>
        <nav className="navbar navbar-expand navbar-dark bg-dark">
          <a href="/menus" className="navbar-brand">
            Blue Devil Cafe Online
        </a>
          <div className="navbar-nav mr-auto">
            <li className="nav-item">
              <Link to={"/home"} className="nav-link">
                Home
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/calendar"} className="nav-link">
                Calendar
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/cart"} className="nav-link">
                Cart
            </Link>
            </li>
            <li className="nav-item">
              <Link to={"/login"} className="nav-link">
                Login
            </Link>
            </li>
          </div>
        </nav>

        <div className="container mt-3">
          <Switch>
            <Route exact path={"/home"} component={Home} />
            <Route exact path={"/calendar"} component={Calendar} />
            <Route exact path={"/cart"} component={Cart} />
            <Route exact path={"/login"} render = {() => <Login handleLogonChange = {this.handleLogonChange}/>} /> 
          </Switch>
        </div>

      </div>
    )
  }
}

此行已修改 => <Route exact path={"/login"} render = {() => <Login handleLogonChange = {this.handleLogonChange}/>} />

如何在登录文件中使用:

登录.js

props.handleLogon(){  // (or this.props.handleLogon) if class component
    try{
      if(this.username == "user1" && this.password == "pass123"){
        //send info to app.js
       return true
      }
    }
    catch{
      this.setState({
        message: "Incorrect Credentials"
      });
    }
  }

执行此操作的基本方法(您可能应该在继续使用 Redux 或 Context API 之前尝试了解)是传递props 如果您还不熟悉props ,您应该前往文档以获得完整的解释。

当您在 JSX 中包含子组件时,只需将该数据值声明为 prop,即可将数据从父组件传递给子组件。 通过将函数作为道具传递,然后可以更新父级中的状态,您可以将数据从子级传递给父级。

在你的例子中,我们可以做这样的事情。 我们需要在这里使用 render 方法将 props 传递给路由:

<Route exact path={"/login"} render={() => <Login handleLogonChange={this.handleLogonChange}/>} />

然后在Login组件中,从 props 调用函数:

handleLogon(){
    try{
      if(this.username == "user1" && this.password == "pass123"){
        this.props.handleLogonChange(true);
      }
    }
    catch{
      this.setState({
        message: "Incorrect Credentials"
      });
    }
  }

暂无
暂无

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

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