S.Asenov
S.Asenov

Reputation: 144

How to preserve value in react component even when the component updates and rerenders

I would like to preserve a value in a react component even when the component has been updated and rerendered. I usually store it in the parent component, but in this case the parent component updates too so this is not an option.

In the following example I need to preserve the scrollTop position of a div element. The way I do it is by storing the value in a global variable. Is there a way to do it without using global variables?

import React, { useRef, useEffect } from 'react';
import ItemsList from './ItemsList';

const ItemsListContainer = (props) => {
    let elementRef = useRef(null);

    useEffect(() => {
        elementRef.current.scrollTop = window['scrollPos'];
    });

    function storeScrollPosition() {
        window['scrollPos'] = elementRef.current.scrollTop;
    }

    return (
        <div className="items-list-container" ref={elementRef} onScroll={storeScrollPosition}>
            <ItemsList context={props.context}></ItemsList>
        </div>
    )
}

export default ItemsListContainer;

Upvotes: 1

Views: 4149

Answers (1)

claud.io
claud.io

Reputation: 1953

let elementRef = useRef(null);

useEffect(() => {
    elementRef.current.scrollTop = window['scrollPos'];
});

By doing this you are setting the scrollTop value at each render. If you want to preserve the value use useMemo instead

const myValue = useMemo(() => {
 return window['scrollPos'];
},[]);

the empty array means that useMemo have no dependecy so it will be evaluated only the first time


Using context:

export const CustomContext = React.createContext({});

export const App: React.FC = () => {
  const [value, setValue] = useState()
  return <CustomContext.Provider value={{ value, setValue }}>
       //wrapped code
    </CustomContext.Provider>;
};

inside any child component you can access to it by

const { value, setValue } = React.useContext(CustomContext);

useEffect(() => {
    setValue(window['scrollPos'])
});

using local store

just take a look at lockr

Lockr.set('value', window['scrollPos'];)
Lockr.get('value');

Upvotes: 1

Related Questions