【问题标题】:Rendering different navbars based on state根据状态渲染不同的导航栏
【发布时间】:2020-11-21 16:25:14
【问题描述】:

我遇到了条件渲染问题。我创建了一个状态,我测试它是真还是假,每个状态都会呈现不同的导航栏:普通用户为 1,管理员为 1。我已经确定我的登录组件可以正常工作,因为当我在登录页面上单击提交时,它会发送正确的数据以将 app.js 中的“isLoggedIn”状态切换为 true。这里出现的问题是导航栏没有改变,当我转到基本页面“localhost:8081/”时,url 显示了登录时应该显示的正确页面,但它没有呈现。我将在下面发布我的代码,如果您有任何想法或需要更多信息,请告诉我!

App.js

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

这是用户导航:

这是管理导航:

这也是我几天前询问的关于在组件之间发送数据的帖子: How to pass data between 2 classes in ReactJS?

【问题讨论】:

  • 您能否添加其他详细信息以帮助我们识别问题。
  • @TheMisir 我从渲染上方添加了 2 个函数,真的没有什么其他的了。你有什么猜测吗?
  • 您可以尝试渲染类似render() { return &lt;span&gt;{this.state.isLoggedIn ? 'logged in' : 'not logged in'}&lt;/span&gt; } 的内容,以检查问题是否与此组件或其他问题有关。
  • 但除此之外,我认为通过代码,问题很简单,渲染只被调用一次,它是改变渲染函数的JSX,你需要把条件放在JSX里面,那样它会改变,或者你可以使用componentDidUpate函数
  • 渲染在你的代码到达handleLogonChange之前被调用wayyy,这就是为什么我猜它没有像它应该的那样响应,解决方案很简单,但需要更多图像

标签: javascript reactjs


【解决方案1】:

这可能不是您想要的,但我建议您可能想做的第一件事是将导航更改为它们自己的组件。像这样。

const AdminNav = () => (
  <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>
);

const UserNav = () => (
  <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>
);

// Your render function will look something like this.
render() {
    return this.state.isLoggedIn ? <AdminNav /> : <UserNav />;
}

然后要调试这个问题,你可以记录isLoggedIn 状态,你也没有提到你是如何更新状态的。所以只要状态正在更新就可以了。

【讨论】:

  • 我现在就试试这个,我正在从我的登录文件中更新 isLoggedIn 状态,该文件是 app.js 的子文件,所以我有一个 props 语句来处理app.js 状态。
  • 状态更新是否正确?我的意思是尝试在渲染方法中记录您的状态并检查它是否真的正确更新
  • 你是对的。在进行了更多测试后,我发现子组件实际上并未正确更改状态。
  • 这帮助我解决了我在这个问题上遇到的问题,至于出现的另一个问题,我自己也想通了,所以我将其标记为正确。
猜你喜欢
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多