我使用它已经有一段时间了,研究useRef和forwardRef只是为了能够将跳过导航链接添加到我的Reaction项目中.因为多个来源都说ElementByID和querySelector不是正确的方法,所以我最终将一个引用转发到我的所有路由.然后,在每一页上,我将引用进一步转发到引用主组件.对于一个小的可访问性功能来说,这一切似乎都是一个巨大的复杂问题.

const App = () => {
  const beginningOfMainRef = useRef(null);

  const handleFocusMain = () => beginningOfMainRef.current.focus();

  return (
    <Theme>
      <GlobalStyle />
      <SkipNavigationButton onClick={handleFocusMain}>
        Skip Navigation Links
      </SkipNavigationButton>
      <Header />
      <Routes>
        <Route path="/" element={<HomePage ref={beginningOfMainRef} />} />
        <Route
          path="/distributors"
          element={<DistributorsPage ref={beginningOfMainRef} />}
        />
        <Route
          path="/contacts"
          element={<ContactsPage ref={beginningOfMainRef} />}
        />
      </Routes>
      <Footer />
    </Theme>
  );
};
export default App;

比每一页都要多:

const AboutPage = forwardRef((props, ref) => {
  return (
    <RefMain ref={ref}>
      <h1>hi, i'm about</h1>
    </RefMain>
  );
});
export default AboutPage;

最后是:

const RefMain = forwardRef((props, ref) => {
  return (
    <Main>
      <BeginningOfMain tabIndex="-1" ref={ref}>
        {props.title} main content
      </BeginningOfMain>
      {props.children}
    </Main>
  );
});

export default RefMain;

这当然是一个简化的例子,页数减少了.看着裁判通过的路由,他们什么都不是,而不是枯燥的.我是不是错过了什么绝妙的把戏?我try 在RefMain组件中使用useRef,但这使我无法将引用传递给树中更高的处理程序函数(App.js).

推荐答案

由于在每个被路由的组件中都应用了RefMain,因此最好将其抽象为布局布线组件,而不是每个页面内容的包装组件.它不是呈现childrenprops ,而是呈现Outlet组件,以便嵌套路由将其内容呈现到其中.

const RefMain = forwardRef((props, ref) => {
  const [title, setTitle] = React.useState();

  return (
    <Main>
      <BeginningOfMain tabIndex="-1" ref={ref}>
        {title} main content
      </BeginningOfMain>
      <Outlet context={{ setTitle }} />
    </Main>
  );
});

export const RefWrapper = ({ children, title }) => {
  const { setTitle } = useOutletContext();
  React.useEffect(() => {
    setTitle(title);
  }, [title]);

  return children;
};

export default RefMain;
const AboutPage = () => {
  return (
    <h1>hi, i'm about</h1>
  );
}
export default AboutPage;

当页面位置更新时,可以使用另一个ref和div元素将焦点设置回页面顶部.

const App = () => {
  const topRef = useRef();
  const beginningOfMainRef = useRef(null);

  const location = useLocation();

  useEffect(() => {
    topRef.current.scrollIntoView();
    topRef.current.focus();
  }, [location.pathname]);

  const handleFocusMain = () => beginningOfMainRef.current.focus();

  return (
    <Theme>
      <div ref={topRef} tabIndex={-1} />
      <GlobalStyle />
      <SkipNavigationButton onClick={handleFocusMain}>
        Skip Navigation Links
      </SkipNavigationButton>
      <Header />
      <Routes>
        <Route element={<RefMain ref={beginningOfMainRef} />}>
          <Route path="/" element={<HomePage />} />
          <Route
            path="/distributors"
            element={(
              <RefWrapper title="Distributors">
                <DistributorsPage />
              </RefWrapper>
            )}
          />
          <Route
            path="/contacts"
            element={(
              <RefWrapper title="Contacts">
                <ContactsPage />
              </RefWrapper>
            )}
          />
        </Route>
      </Routes>
      <Footer />
    </Theme>
  );
};

export default App;

我没有站在任何沙箱来测试这一点,但我相信它应该接近您所描述的期望行为.如果有问题,让我知道,我会在现场演示工作.

Reactjs相关问答推荐

为什么安装FLOBIT后,所有的输入FIELD现在都有一个蓝色的轮廓?

有没有办法让两个状态在两次精准渲染中更新?

错误./src/TopScroll.js 31:21-31导出';(作为';随路由导入)在';Reaction-Router-Dom';中找不到

如何在React中正确地将密码输入类型切换为文本或反之亦然(下一页)

在 useSelector() 中使用 array.map() 如何导致组件在分派操作时重新渲染?

如何更改TimePicker中下拉菜单的背景 colored颜色 和字体 colored颜色 - MUI React

React Native - 如何处理错误带有有效负载的NAVIGATE操作..未被任何导航器处理?

修改React数据表扩展组件

是否可以直接在 jsx 标签上使用 CSS 定义的 colored颜色 ?

根据其中的值不同地react setState 更新状态

我正在try 将一组加载程序函数发送到我的路由,它抛出一个错误 Handler is not a funtion in a reactJs application

来自一个自定义 React Native 组件的样式从另一个自定义组件移除样式

React:如何设置光标 Select

null 不是对象(判断RNSound.IsAndroid)

添加新行时自动打开可扩展表格(Antd 表格,ReactJS)

antd 找不到 comments

如果传递给挂钩的数据需要事先修改,如何使用自定义挂钩?

使用 useRef(uuid()) 的目的是什么?

找不到元素 - 这是参考问题吗?

服务器端分页未按预期工作