繁体   English   中英

反应如何使有条件渲染的导航持续存在

[英]React how to make conditionally rendered navigation persist

我正在学习 React 并且正在创建一个 React 桌面应用程序,其中侧面导航必须根据用户的当前位置(由应用程序正文中的标准导航按钮确定)而改变。

该应用程序可在此处访问: https://codesandbox.io/s/conditional-navigation-di8t5?file=/pages/Start.jsx

当用户在应用程序中移动时,我能够使导航选项有条件地呈现。 例如:从“开始”到“页面 A”,再到“页面 B”。 问题是当他们回到之前的位置时,导航也会恢复。 我希望这样一旦用户到达页面 B 并返回页面 A,页面 B 仍然可以在侧导航中访问。

从研究来看,使用 React Context API 似乎是最好的解决方案。 是这种情况,还是我缺少更简单的方法? 谢谢你。

您可以采用c0m1t提到的使用useLocation来跟踪当前位置的方法。

为了能够始终如一地跟踪位置以及出于其他更多的组织原因,我还建议您稍微更改应用程序结构。

我认为当前结构的一个问题是Layout是每个页面组件的子组件。 相反,我认为这个组件更适合作为页面的父级,而不是让每个页面都呈现一个Layout组件。 这同样适用于您的Header组件。

我建议将您的App.js文件更改为以下内容:

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Header />
      <Layout>
        <Switch>
          <Route exact path="/" component={Start} />
          <Route exact path="/page-A" component={PageA} />
          <Route exact path="/page-B" component={PageB} />
          <Route exact path="/page-C" component={PageC} />
        </Switch>
      </Layout>
    </ThemeProvider>
  );
}

我也不认为每个屏幕都需要不同的Menu组件。

您可以改为使用通用Menu组件并在Layout组件中呈现此组件:

const Layout = (props) => {
  return (
    <React.Fragment>
      <Grid container>
        <Grid item xs={3} className="side-nav">
          <Menu />
        </Grid>
        <Grid item xs={9} className="main">
          <Box p={4}>{props.children}</Box>
        </Grid>
      </Grid>
    </React.Fragment>
  );
};

然后您可以将Menu组件更改为:

const pageLocations = ["/page-A", "/page-B", "/page-C"];
const pages = ["Page A", "Page B", "Page C"];

const Menu = () => {
  const location = useLocation();
  const [locations, setLocations] = React.useState([]);

  React.useEffect(() => {
    const currentPath = location.pathname;
    if (!locations.includes(currentPath)) {
      setLocations([...locations, currentPath]);
    }
  }, [location, locations, setLocations]);

  return (
    <Box>
      <MenuList>
        {pages.map((page, i) => {
          return (
            <MenuItem
              key={i}
              to={pageLocations[i]}
              className={locations.includes(pageLocations[i]) ? "" : "deactive"}
              component={NavLink}
            >
              {page}
            </MenuItem>
          );
        })}
      </MenuList>
    </Box>
  );
};

所以方法是从菜单中跟踪之前访问过的所有页面。 位置映射到每个菜单项的方式是,我们可以根据已访问的所有位置以及映射到菜单项的位置来检查是否应显示菜单项。

此答案不处理您从特定页面的 url 开始的情况,例如/page-A而不是/


沙盒示例

暂无
暂无

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

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