简体   繁体   English

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

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

I am having an issue with what I believe is react hooks for a school assignment.我对我认为是学校作业的反应钩子有疑问。

In my app.js, I am using conditional rendering to render 2 different navbar's: 1 for a normal user and 1 for an admin.在我的 app.js 中,我使用条件渲染来渲染 2 个不同的导航栏:1 个用于普通用户,1 个用于管理员。 I am having trouble understanding how to change the app.js state where I render the navbar, from the login.js.我无法理解如何从 login.js 更改呈现导航栏的 app.js 状态。 Below is my code.下面是我的代码。

Login.js登录.js

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

App.js应用程序.js

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

    this.state = {
      isLoggedIn: false
    }
  }

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

App.js rendering 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>
      )
    }
  }

What I want to send from login is a true boolean to the app so that it can render the change the condition to render the admin's navbar isntead of the general user's navbar.我想从登录发送的是一个真正的布尔值到应用程序,以便它可以呈现更改条件以呈现管理员的导航栏而不是一般用户的导航栏。 If there is anything else you need please let know.如果您还有什么需要,请告诉我们。

Try using the render method instead of component on the Route.尝试在 Route 上使用 render 方法而不是组件。 In that way, you can pass the function as a prop reference to Login and get value from child to update the parent.这样,您可以将该函数作为道具引用传递给 Login 并从 child 获取值以更新 parent。

Here is the code:这是代码:

//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>
    )
  }
}

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

How to use in Login file:如何在登录文件中使用:

Login.js登录.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"
      });
    }
  }

The basic way to do this, which you should probably try to get an understanding of before moving on to Redux or the Context API, is by passing props .执行此操作的基本方法(您可能应该在继续使用 Redux 或 Context API 之前尝试了解)是传递props If you aren't already familiar with props , you should head over to the docs for a full explanation.如果您还不熟悉props ,您应该前往文档以获得完整的解释。

You pass data from a parent component to a child by simply declaring that data value as a prop when you include the child component in your JSX.当您在 JSX 中包含子组件时,只需将该数据值声明为 prop,即可将数据从父组件传递给子组件。 You pass data from a child to a parent by passing a function as a prop which can then update the state in the parent.通过将函数作为道具传递,然后可以更新父级中的状态,您可以将数据从子级传递给父级。

In your example we can do something like this.在你的例子中,我们可以做这样的事情。 We need to use the render method here to pass props to a route:我们需要在这里使用 render 方法将 props 传递给路由:

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

Then in the Login component, call the function from props:然后在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