Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

force full rerender/data refresh on unfreeze #37

Open
fridaystreet opened this issue Aug 7, 2024 · 0 comments
Open

force full rerender/data refresh on unfreeze #37

fridaystreet opened this issue Aug 7, 2024 · 0 comments

Comments

@fridaystreet
Copy link

fridaystreet commented Aug 7, 2024

Apologies if this is a stupid question, but is there a way to essentially force some components to refresh/drop their data and fully rerender after unfreeze?

Scenario example.

I have a bunch of tabs, some of the tabs have live data so when they unfreeze they are up to date and all works great. But some of the tabs I want to always refetch their data as we either currently don't have a live update or it's not something that lends itself to live data. (eg some dashboard data that is caluclated on the backend and isn't live)

I've tried using a combination of freeze wrapped and non wrapped components in the tabs content, but this doesn't work well, either breaks layout or more often just causes the ones I do want to fully refresh to always fully rerender and refresh their data (I assume do to tree changing or something)

The below feels very hacky so would just like to know if there is a better/proper way to do this?

many thanks in advance.

what I've tried:

eg something like this doesn't seem to work and causes the freeze tabs to always fully rerender, I'm guessing as stack order has changed

<div class="tabcontent">
    <Freeze freeze={'tab1' !== selectedTab} ><Tab1 /></Freeze>
    <>{'tab2' === selectedTab && <Tab2 />}</>
    <Freeze freeze={'tab3' !== selectedTab} ><Tab3 /></Freeze>
</div>

so I tried the following and using the freeze prop on tab2 to return null inside tab2 component when freeze true, that way the order of the child stack should be the same, but this totally screwed up all the layout

<div class="tabcontent">
    <Freeze freeze={'tab1' !== selectedTab} ><Tab1 /></Freeze>
    <Tab2 freeze={'tab2' !== selectedTab} />
    <Freeze freeze={'tab3' !== selectedTab} ><Tab3 /></Freeze>
</div>

So the only way I've been able to make it work is to wrap freeze around everything and put a useEffect hack from a ref inside the components I want to cause their data to refretch. For some reason you have to use the ref for the comparison in the refresh property. if you use the state, it never changes inside the component.

const { selectedTab } = useContext(TabContext)
const selectedTabRef = useRef()

useEffect(() => {
    selectedTabRef.current = selectedTab
}, [selectedTab, selectedTabRef])

<div class="tabcontent">
    <Freeze freeze={'tab1' !== selectedTab} ><Tab1 /></Freeze>
    <Freeze freeze={'tab2' !== selectedTab} ><Tab2 refresh={'tab2' !== selectedTabRef.current} /></Freeze>
    <Freeze freeze={'tab3' !== selectedTab} ><Tab3 /></Freeze>
</div>

Heres the basic example of logic in tab2 to cause the refresh. What seems to happen is that when unfreezing this tab, selectedTabRef.current is still set to the previous tab, so refresh property is then set to true as it unfreezes. This only happens if comparing to a ref, if I compare directly to the selectedTab prop it never changes inside tab2

Tab2 gets that value (only when using the ref). This causes the useEffect to fire inside tab2. Once it's unfrozen, selectedTabRef.current has updated and ('tab2' !== selectedTabRef.current) = false so refresh prop inside tab2 is then also false.

const Tab2 = ({ refresh }) => {

  const [refreshData, setRefreshData] = useState()
 const [data, setData] = useState()

const fetchData = useCallback(() => {
   ...some code that fetches data and stores in data var 
}, []) 

useEffect(() => {
...some code that calls fetchdata on first render
}, [])


  useEffect(() => {
    if (refresh) {
      if (!refreshData && data) {
        setRefreshData(true)
        fetchData()
      }
      return
    }
    if (refreshData) setRefreshData()
  }, [refresh, refreshData, setRefreshData, fetchData, data])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant