Skip to content

Instantly share code, notes, and snippets.

@pie6k
Last active October 28, 2021 18:57
Show Gist options
  • Save pie6k/20beb73aaceac2bb9d02e929514da2f9 to your computer and use it in GitHub Desktop.
Save pie6k/20beb73aaceac2bb9d02e929514da2f9 to your computer and use it in GitHub Desktop.
<Freeze /> React Component
/**
* Goal:
*
* Being able to freeze some part of react tree and stop all updates from 'react word' for part of the tree for some period of time.
* It would prevent ui from updating in any way (props change, state change, hooks change etc)
*
* Use case:
*
* Let's say there is tab based react-native app.
* All of the screens are rendered all the time, and by using some store (redux etc)
* changes made in one tab might get reflected in another tab.
*
* Inactive tab might also have some inner updates (like clock components etc)
*
* We don't really want that as we dont even see inactive tab.
*
* But because of complexity, it might be hard to disable all updates easily eg.
* - it might be listening to relay/apollo updates
* - it might be listening to redux or other store
* - it might just have some inner timers or state that updates frequently (eg. <CountDown /> component we cannot manually stop)
* - etc
*
* Technically it would be possible to create some sort of context near the top of the tree like isFocusedContext,
* but again, it would require all different kinds of components to properly enable/disable updates using it
*
*
* API
*
* There would be special component called `Freeze`, and everything inside it would ignore
* every update in react word (both props and state/hooks based)
*
* ```
* <Freeze isEnabled>
* <Clock />
* </Freeze>
* ```
*
* Even if there would be some component like `<CountDown />` inside <Freeze>, that has some inner state that is updating every second, those updates would be ignored by react and not reflected in the UI
* until `isEnabled` prop becomes false.
*
* Technically, those components would update their states (eg. <CountDown /> also has `ticksCount` that increases every second).
* This `tickCount` would increase normally, but updates would not be rendered. However, when we'd `unfreeze` it, we would see accurate state
*
* When updates are enabled again, entire tree would be re-rendered and become 'live' again
*
*
*/
@reme3d2y
Copy link

const Freezer = React.memo<{ children: ReactNode; freeze: boolean }>(
    ({ children }) => <React.Fragment>{ children }</React.Fragment>,
    (_, nextProps) => nextProps.freeze,
);

// usage
<Freezer freeze={ freeze}>
    <div>
       The part of the component that should not change when freeze flag is true
    </div>
</Freezer>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment