【问题标题】:how to show a component on specific pages如何在特定页面上显示组件
【发布时间】:2021-01-15 17:38:14
【问题描述】:

我想在用户登录时显示navbar

当用户按下登录按钮时,我将页面替换为主页

我尝试定义使用状态,如果路径名不等于 /login/step-two 将其设置为 true 然后在应用程序中我说如果 usestate 等于 true 则显示导航栏

但我在刷新页面之前看不到导航栏

这是我在useeffect中尝试过的

  const [hasNavBar, setNavBar] = useState(false)
useEffect(() => {
    console.log(history.location.pathname);
    if (history.location.pathname !== '/login'|| history.location.pathname !=='/step-two'
    ) {
      setNavBar(true)
    }
  }, []) 

这是完整的代码

    const App = () => {
      const [hasNavBar, setNavBar] = useState(false)
      useEffect(() => {
        console.log(history.location.pathname);
        if (history.location.pathname !== '/login' ||
          history.location.pathname !== '/step-two'
        ) {
          setNavBar(true)
        }
      }, [])
      return (
        <div>
          <SNackbar></SNackbar>
          <Router history={history}>
            <div>
              <Route path="/login" exact component={FirstLogin} />
              <Route path="/step-two" exact component={SecondLogin} />
              <Route path="/home" exact component={Home} />
              <Route path='/ranking-list' exact component={RankingListPage} />
            </div>
          </Router>
          <div>
          {hasNavBar ?
            <div>
              <BottomNavBar />
            </div> : ''
          }
          </div>
        </div>
      )
    };
    
    export default App;

更新

我尝试使用 history.listen bu 仍然看到相同的错误
const App = () => {
  const [hasNavBar,setnavbar]=useState(false)
  useEffect(() => {
    history.listen(()=>{
      if (history.location.pathname === '/'||history.location.pathname === '/steptwo') {
        setnavbar(false);
      }else{setnavbar(true);}
        
      
    })
    if (localStorage.getItem("token") && history.location.pathname === '/') {
      history.replace('/home');
    }
  }, [])
  return (
    <div>
      <SNackbar></SNackbar>
      <Router history={history}>
        <div>
          <Route path="/" exact component={FirstLogin} />
          <Route path="/steptwo" exact component={SecondLogin} />
          <Route path="/home" exact component={Home} />
          <Route path='/ranking-list' exact component={RankingListPage} />
        </div>
      </Router>
      {hasnavbar?
       <div 
       style={{ position: 'fixed', bottom: '0px', width: "100%", height: '80px' }}>
        <BottomNavBar />
      </div>:''
      }
    </div>
  )
};

export default App;

【问题讨论】:

  • 尝试将{hasnavbar?替换为{hasNavBar?,因为它与您的使用状态不同

标签: javascript reactjs routes react-router


【解决方案1】:

正如@lissettdm 所说的

你需要使用history.listen在历史改变时调用一个函数
但不需要在Router中包裹App

如果您不使用history.listen,则usestate 只会在您刷新页面时更改,因为useeffect 将在刷新时运行

您可以将其默认值定义为 false,并且只要它不在条件中,它就会为 true 一个 else 语句,这样每当您更改路由时,它就会被调用并将 hasavbar 设置为 true

  const [hasnavbar,setnavbar]=useState(false)
  useEffect(() => {
    history.listen(()=>{
      if (history.location.pathname === '/login'||history.location.pathname === '/steptwo') {
        setnavbar(false);
      }else{setnavbar(true);}   
    })
  }, [])

这是完整的代码

const App = () => {
  const [hasnavbar,setnavbar]=useState(false)
  useEffect(() => {
    history.listen(()=>{
      if (history.location.pathname === '/login'||history.location.pathname === '/steptwo') {
        setnavbar(false);
      }else{setnavbar(true);}    
    })
  }, [])
  return (
    <div>
      <SNackbar></SNackbar>
      <Router history={history}>
        <div>
          <Route path="/login" exact component={FirstLogin} />
          <Route path="/steptwo" exact component={SecondLogin} />
          <Route path="/home" exact component={Home} />
          <Route path='/ranking-list' exact component={RankingListPage} />
        </div>
      </Router>
      {hasnavbar?
       <div>
        <BottomNavBar />
      </div>:''
      }
    </div>
  )
};

export default App;

【讨论】:

  • 我得到了同样的结果
【解决方案2】:

将 App 封装在 Router 组件中并监听历史变化:

index.js

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById("root")
);

App.js

const history = useHistory();
useEffect(() => {
 return history.listen(location => {
   if (
    history.location.pathname !== "/login" &&
    history.location.pathname !== "/step-two"
   ) {
     setNavBar(true);
   }
  });
}, []);

查看工作示例:https://stackblitz.com/edit/react-5xd5d1?file=src%2FApp.js

【讨论】:

  • 我可以使用多个使用效果吗?因为当前的 useEffect 做了多个动作,所以我认为我应该为此不同的一个
  • 是的,您可以使用多个 useEffect。
  • 我试过了,我得到了相同的结果,我应该再次刷新页面以查看结果
  • 能否检查每次路由变化时是否执行了这个useEfffect?
  • 你的意思是依赖?如果是,我检查了它,并确保我通过了[history.location.pathname] 并且仍然相同,我的代码有什么问题吗?
【解决方案3】:
  1. 把你useEffect的逻辑从||改成&amp;&amp;,现在没有意义了。

  2. 尝试使用useLocation 挂钩:

import { useLocation } from 'react-router-dom';

...

let location = useLocation();

...

if (location.pathname !== '/login' && location.pathname !== '/step-two') { ... }

【讨论】:

  • Cannot read property 'location' of undefined 出现此错误
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多