简体   繁体   中英

How save scroll position and add to state in React.js?

I have MainWrapper where api request, returns object with items(20pcs). Data api response i transfer to component(main page in routing). In MainWrapper have two routs: main page and detail page.

<Switch>
  <Route
    exact
    path="/"
    render={(props) => (
      <PokemonCardContainer
        pokemons={pokemons}
        search={search}
        loading={loading}
        error={error}
        lastPokemonElementRef={lastPokemonElementRef}
        handleSearch={handleSearch}
      />
    )}
  />
  <Route exact path="/pokemon/:pokemonName" component={Pokemon} />
</Switch>

In main page i construct list with items. When I reach the end of the list, api request updated and add new 20psc items in list and etc. Also next to each item there is button leads to detail page this item. I want save scroll position when go to detail page and when I come back the position was on the element by which I clicked . In component which is main page i create new state:

const [scrollPosition, setScrollPosition] = useState([0, 0]);

Next I made a click handler where I can find out the coordinates of the scroll:

const getCurrentScrollPosition = (e) => {
    e.preventDefault();
    let cordsAfterClick = [];
    let cords = ["scrollX", "scrollY"];
    cords.forEach((cord) => {
      cordsAfterClick.push(window[cord]);
    });
    console.log("Array with cords: ", cordsAfterClick);
    setScrollPosition(cordsAfterClick);
    console.log("State scrollPosition after update state: ", scrollPosition);
  };

在此处输入图像描述

ps: and i see setScrollPosition does not update state... e.preventDefault() - only for test. And i use:

useEffect(() => {
    window.scrollTo(scrollPosition[0], scrollPosition[1]);
  }, [scrollPosition]);

UPD: Code updated. The comments below helped to understand the problem. State:

const [scrollPosition, setScrollPosition] = useState({
    scrollX: 0,
    scrollY: 0,
  });

Click handler:

const getCurrentScrollPosition = (e) => {
    let cordsAfterClick = {};
    let cords = ["scrollX", "scrollY"];
    cords.forEach((cord) => {
      cordsAfterClick[cord] = window[cord];
    });
    localStorage.setItem("scrollCord", JSON.stringify(cordsAfterClick));
  };

useEffect:

useEffect(() => {
    setScrollPosition((prevScrollCord) => {
      return {
        ...prevScrollCord,
        ...JSON.parse(window.localStorage.getItem("scrollCord")),
      };
    });
    window.scrollTo(scrollPosition.scrollX, scrollPosition.scrollY);
  }, [scrollPosition.scrollX, scrollPosition.scrollY]);

You have to listen for the scroll event inside a useEffect like this:

useEffetch(() => {
  const handleScroll = e => {
   // set scroll values in state
  }

  window.addEventListener('scroll', handleScroll);

  // Remove listener when component unmounts
  window.removeEventListener('scroll', handleScroll);
}, [])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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