admin管理员组

文章数量:1023221

I've got a React app with URLs defined with React Router:

const App: React.FC = (): JSX.Element => {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/rules" />
        <Route
          exact
          path={["/rules", "/rules/:placeId"]}
          ponent={LandingPage}
        />
        <Route
          exact
          path={["/route", "/route/:start/:end"]}
          ponent={RoutePage}
        />
      </Switch>
    </Router>
  );
};

I want to allow the user to go to a specific accordion of the document if the url contains a hash part like this /rules/someplace#accordion-3

I have a ponent that returns the accordions in question, which all have an id:

const CategoryDisplay: React.FC<Props> = (props) => {
...
  return (
    <>
      <Accordion
        id={`category-${accordion.id}`}/>
    </>
  );
};

export default CategoryDisplay;

And when I open an URL with an anchor like /rules/someplace#accordion-3 while I'm already on the page, everything works fine and it scrolls to the element. However, on the initial load of the page, this behavior doesn't work.

How would I go about scrolling to the element only after the page has loaded?

I've got a React app with URLs defined with React Router:

const App: React.FC = (): JSX.Element => {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/rules" />
        <Route
          exact
          path={["/rules", "/rules/:placeId"]}
          ponent={LandingPage}
        />
        <Route
          exact
          path={["/route", "/route/:start/:end"]}
          ponent={RoutePage}
        />
      </Switch>
    </Router>
  );
};

I want to allow the user to go to a specific accordion of the document if the url contains a hash part like this /rules/someplace#accordion-3

I have a ponent that returns the accordions in question, which all have an id:

const CategoryDisplay: React.FC<Props> = (props) => {
...
  return (
    <>
      <Accordion
        id={`category-${accordion.id}`}/>
    </>
  );
};

export default CategoryDisplay;

And when I open an URL with an anchor like /rules/someplace#accordion-3 while I'm already on the page, everything works fine and it scrolls to the element. However, on the initial load of the page, this behavior doesn't work.

How would I go about scrolling to the element only after the page has loaded?

Share Improve this question asked Aug 5, 2021 at 13:10 snow catsnow cat 632 silver badges9 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

I think the idea would be to use an effect to scroll to the appropriate ponent after the ponent mounts. Perhaps something like this:

React.useEffect(() => {
    const anchor = window.location.hash.slice(1);
    if (anchor) {
        const anchorEl = document.getElementById(anchor);
        if (anchorEl) {
            anchorEl.scrollIntoView();
        }
    }
}, []);

Notes:

  • I haven't tested this.
  • useLayoutEffect instead of useEffect may give a better experience here; see this article for details.
  • I'm bypassing React and using the DOM. I usually try to avoid that, but since this logic is isolated and inherently focused on browser DOM behavior, I think this is a good use case for it (instead of plicating the code by pulling in more interactions with your React ponents.)
  • scrollIntoView is convenient but experimental; consider using the scroll-into-view-if-needed NPM package instead.

I don't know if I understand correctly.

I think, you should make a function for wait everything plete.

but, if you can't catch exactly timing when everything fine, you can use trick.

example :

    const CategoryDisplay: React.FC<Props> = (props) => {
        ...
        const [accordionId, setAccordionId] = useState("");
        useEffect(()=>{
          // this ponent mounted
          ...
          setTimeout(()=>{
            // do something
            setAccordionId(`category-${accordion.id}`);
          },0);
        }, []);
        return (
          <>
            <Accordion
              id={accordionId}/>
          </>
        );
    };

This will definitely run in the frame after the ponent mounted.

I've got a React app with URLs defined with React Router:

const App: React.FC = (): JSX.Element => {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/rules" />
        <Route
          exact
          path={["/rules", "/rules/:placeId"]}
          ponent={LandingPage}
        />
        <Route
          exact
          path={["/route", "/route/:start/:end"]}
          ponent={RoutePage}
        />
      </Switch>
    </Router>
  );
};

I want to allow the user to go to a specific accordion of the document if the url contains a hash part like this /rules/someplace#accordion-3

I have a ponent that returns the accordions in question, which all have an id:

const CategoryDisplay: React.FC<Props> = (props) => {
...
  return (
    <>
      <Accordion
        id={`category-${accordion.id}`}/>
    </>
  );
};

export default CategoryDisplay;

And when I open an URL with an anchor like /rules/someplace#accordion-3 while I'm already on the page, everything works fine and it scrolls to the element. However, on the initial load of the page, this behavior doesn't work.

How would I go about scrolling to the element only after the page has loaded?

I've got a React app with URLs defined with React Router:

const App: React.FC = (): JSX.Element => {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/rules" />
        <Route
          exact
          path={["/rules", "/rules/:placeId"]}
          ponent={LandingPage}
        />
        <Route
          exact
          path={["/route", "/route/:start/:end"]}
          ponent={RoutePage}
        />
      </Switch>
    </Router>
  );
};

I want to allow the user to go to a specific accordion of the document if the url contains a hash part like this /rules/someplace#accordion-3

I have a ponent that returns the accordions in question, which all have an id:

const CategoryDisplay: React.FC<Props> = (props) => {
...
  return (
    <>
      <Accordion
        id={`category-${accordion.id}`}/>
    </>
  );
};

export default CategoryDisplay;

And when I open an URL with an anchor like /rules/someplace#accordion-3 while I'm already on the page, everything works fine and it scrolls to the element. However, on the initial load of the page, this behavior doesn't work.

How would I go about scrolling to the element only after the page has loaded?

Share Improve this question asked Aug 5, 2021 at 13:10 snow catsnow cat 632 silver badges9 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

I think the idea would be to use an effect to scroll to the appropriate ponent after the ponent mounts. Perhaps something like this:

React.useEffect(() => {
    const anchor = window.location.hash.slice(1);
    if (anchor) {
        const anchorEl = document.getElementById(anchor);
        if (anchorEl) {
            anchorEl.scrollIntoView();
        }
    }
}, []);

Notes:

  • I haven't tested this.
  • useLayoutEffect instead of useEffect may give a better experience here; see this article for details.
  • I'm bypassing React and using the DOM. I usually try to avoid that, but since this logic is isolated and inherently focused on browser DOM behavior, I think this is a good use case for it (instead of plicating the code by pulling in more interactions with your React ponents.)
  • scrollIntoView is convenient but experimental; consider using the scroll-into-view-if-needed NPM package instead.

I don't know if I understand correctly.

I think, you should make a function for wait everything plete.

but, if you can't catch exactly timing when everything fine, you can use trick.

example :

    const CategoryDisplay: React.FC<Props> = (props) => {
        ...
        const [accordionId, setAccordionId] = useState("");
        useEffect(()=>{
          // this ponent mounted
          ...
          setTimeout(()=>{
            // do something
            setAccordionId(`category-${accordion.id}`);
          },0);
        }, []);
        return (
          <>
            <Accordion
              id={accordionId}/>
          </>
        );
    };

This will definitely run in the frame after the ponent mounted.

本文标签: