Prevent React component subtrees from rendering

Overview


React Freeze

Prevent React component subtrees from rendering.

What is this? 🤔

This library allows for freezing renders of the parts of the React component tree using Suspense mechanism introduced in React 17. The main use-case for this library is to avoid unnecessary re-renders for parts of the app that are not visible to the user at a given moment. It is important to note that while frozen component subtrees are replaced with a placeholder view, the actual components are not unmounted and hence their React state and corresponding native view instances are retained (DOM elements for react-dom or platform-native views for React Native apps) keeping things like scroll position, input state, or loaded images (for <img> components) unchanged.

The most prominent use case is navigation in React Native apps, which is typically follows a stack-based approach. When opening a new screen, we push it onto a stack but also keep the previous screen on the stack in case you want to go back to them later. Since we want to keep all the state on that previous screens, the components rendering it are kept by the stack, which result in them receiving updates (e.g. redux store changes) and getting rendered even thought they are completely obstructed by other screens. With react-freeze, we are able to suspend renders for such screens and as a result save React from doing unnecessary computation (reconciliation, sending view change updates, etc).

Quick start with react-navigation (React Native) 🧭

You have to be using React Native 0.64 or higher and react-navigation 5.x or 6.x.

Thanks to the fact react-navigation relies on react-native-screens we published an updated version of the screens library that takes advantage of the information about which screens should be active. In order to try react-freeze in your React Native app that uses React Navigation you need to upgrade react-native-screens to version 3.9.0:

yarn upgrade [email protected]

If you're building for ios you also need to run

pod install --project-directory=ios

Then enable experimental freeze support using new method we added to screens library. In order to do that, add the following snippet (along with the import) to the main file of your application:

import { enableFreeze } from "react-native-screens";

enableFreeze(true);

The new react-native-screens library is compatible with React Navigation v5 and v6, however, when using React Navigation v5 you also need to enable "screens" support. This can be done by adding call to enableScreens(true) in your main application file and passing detachInactiveScreens option to your navigators (stack / tabs / etc.).

IMPORTANT: The current version of screens/freeze integration, freezes updates only on views that are more than one level deep the stack hierarchy (the top and second to top screens are not freezing). This is necessary for slide-to-go-back functionality to work as by sliding back we may reveal the content that is displayed below. This is something we plan on improving in the future such that only the top screen is not frozen.

Quick start - using Freeze directly (React and React Native)

In order to use this package you'll have to be using React 17 or higher, or React Native 0.64 or higher.

Install react-freeze package from npm:

yarn add react-freeze

Import Freeze component in your app:

import { Freeze } from "react-freeze";

Wrap some components you want to freeze and pass freeze option to control whether renders in that components should be suspended:

function SomeComponent({ shouldSuspendRendering }) {
  return (
    <Freeze freeze={shouldSuspendRendering}>
      <MyOtherComponent />
    </Freeze>
  );
}

Component docs 📚

The react-freeze library exports a single component called <Freeze>. It can be used as a boundary for components for which we want to suspend rendering. This takes the following options:

freeze: boolean

This options can be used to control whether components rendered under Freeze should or should not re-render. If set to true, all renders for components from Freeze subtree will be suspended until the prop changes to false. Additionally, during the time components are "frozen", Freeze component instead of rendering children will render component provided as placeholder parameter removing frozen components from screen while retaining their native view instances and state.

placeholder?: React.ReactNode

This parameter can be used to customize what Freeze component should render when it is in the frozen state (freeze={true}). This is an optional parameter and by default it renders null. Note, that it is best to "freeze" only components that are not visible to the user at given moment, so in general customizing this should not be necessary. However, if replacing frozen views with just null can break layout of you app, you can use this parameter to show a placeholder that will keep all non-frozen parts of your application in the same place.

Known issues 😭

React Native Debugger does not allow profiling

When profiling React-Native apps with React Native Debugger starting React profiler for the app with frozen components throws an error ("Error: Could not find ID for Fiber ...").

Have other problems with react-freeze? Start a New issue.

FAQ

When component subtree is frozen what happens to state changes that are executed on that subtree

All state changes are executed as usual, they just won't trigger a render of the updated component until the component comes back from the frozen state.

What happens to the non-react state of the component after defrost? Like for example scroll position?

Since all the "native views" (DOM elements or platform-specific views in react native) are kept when the component is frozen their state (such as scroll position, text typed into text input fields, etc.) is restored when they come back from the frozen state. In fact, they are just the same component (same DOM nodes for react-dom / same views for react-native).

What happens when there is an update in a redux store that frozen component is subscribed to?

Redux and other state-management solutions rely on manually triggering re-renders for components that they want to update when the store state changes. When component is frozen it won't render even when redux requests it, however methods such as mapStateToProps or selectors provided to useSelector will still run on store updates. After the component comes back from frozen state, it will render and pick up the most up-to-date data from the store.

Can freezing some of my app components break my app? And how?

There are few ways that we are aware of when <Freeze> can alter the app behavior:

  1. When attempting to freeze parts of the app that is visible to the user at a given moment -- in this case the frozen part is going to be replaced by the placeholder (or just by nothing if no placeholder is provided). So unless you really want this behavior make sure to only set freeze to true when the given subtree should not be visible and you expect user to not interact with it. A good example are screens on the navigation stack that are down the stack hierarchy when you push more content.
  2. When you rely on the frozen parts layout to properly position the unfrozen parts. Note that when component is in frozen state it gets replaced by a placeholder (or by nothing if you don't provide one). This may impact the layout of the rest of your application. This can be workaround by making placeholder take the same amount of space as the view it replaces, or by only freezing parts that are positioned absolutely (e.g. the component that takes up the whole screen).
  3. When component render method has side-effects that relay on running for all prop/state updates. Typically, performing side-effects in render is undesirable when writing react code but can happen in your codebase nonetheless. Note that when subtree is frozen your component may not be rendered for all the state updates and render method won't execute for some of the changes that happen during that phase. However, when the component gets back from the frozen state it will render with the most up-to-date version of the state, and if that suffice for the side-effect logic to be correct you should be ok.


Made by Software Mansion and licenced under The MIT License.

Comments
  • Freezing with react navigation bottom-tabs

    Freezing with react navigation bottom-tabs

    Thank you for your work with this library, very excited to put it in production.

    While testing things out almost everything seemed to work smoothly, with the exception of react navigation bottom-tabs. We noticed this specifically on screens with media playing. We have a state update that fires on navigation blur. The media then adjusts play state when that happens. This works as expected when navigating within the same tab.

    However when switching tabs, we ran into some issues. The state does not update on time, causing the media to be frozen in a playing state when navigating to a different tab. The blur event seems to fire appropriately, so my guess is that the previous tab is freezing almost immediately, not allowing side effects.

    Currently running the latest version of all react-navigation libraries and RN 0.64.1

    Would love any feedback on dealing with this scenario.

    Thanks, Tedi

    opened by tedi 4
  • [Android] first onLayout dimensions are 0

    [Android] first onLayout dimensions are 0

    Hello, I'm testing this lib on my project, thought react-native-screen and react-navigation.

    I noticed a small regression on Android, the first onLayout event on a view inside a react-navigation is fired with a width and height to 0 (and then, immediately after, a new event with correct dimensions) with enableFreeze(true)

    {"height": 0, "width": 0, "x": 0, "y": 0}
    {"height": 710.1818237304688, "width": 392.7272644042969, "x": 0, "y": 0}
    

    and by removing enableFreeze, it trigger only one event with the correct dimensions:

    {"height": 710.1818237304688, "width": 392.7272644042969, "x": 0, "y": 0}
    

    Tested on [email protected] && [email protected] with a <View> with a flex: 1 style. Android only (emulator Android 11 and device Android 8.1), I can't reproduce it on iOS.

    Thank you.

    opened by Freddy03h 3
  • Does this mean I can only activate freeze when using native-stack other than stack?

    Does this mean I can only activate freeze when using native-stack other than stack?

    I read the document of react-navigation, and noticed that @react-navigation/native-stack relies on react-native-screens. if I just use @react-navigation/stack, it is still ok that I can use this freeze feature in my app?

    opened by chj-damon 2
  • Not freezing

    Not freezing

    I wanted to try out react-freeze so I decided to set up a test to see the before & after. We have a React Native application with the following navigation structure:

    • Tab bar
      • Stack A
        • Home screen
        • Bunch of screens
      • Stack B
        • Bunch of screens

    In our "Home" screen, I wrote this (maybe overly complex) log-counter-loop, to see if it'd run before and after react-freeze. Unfortunately it's running both with and without the library.

    // Home screen
    React.useEffect(() => {
      const doSomething = async () => {
        for (let i = 0; i < 100; i++) {
          const myPromise = async () => {
            return new Promise(resolve => {
              setTimeout(() => {
                console.log('Ran: ', i);
                resolve(undefined);
              }, 1000);
            });
          };
          await myPromise();
        }
      };
      doSomething();
    }, []);
    

    Top of my index.js:

    import { enableFreeze } from 'react-native-screens';
    enableFreeze(true);
    

    To make sure index.js is the first thing that's ran by the iOS part:

    - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
    {
      #if DEBUG
        return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
      #else
        return [CodePush bundleURL];
      #endif
    }
    

    Here's a screen record for showcasing:

    https://user-images.githubusercontent.com/5333875/141653983-c11b51a6-eac7-4421-8573-621eaec79f54.mov

    opened by gunnartorfis 2
  • Update to React 18

    Update to React 18

    When react-freeze gets installed it creates a warning in projects that use react ^18.0.0:

    npm WARN ERESOLVE overriding peer dependency npm WARN While resolving: [email protected] npm WARN Found: [email protected] npm WARN node_modules/react npm WARN [email protected]"^18.0.0" from the root project npm WARN 10 more (@react-navigation/bottom-tabs, ...) npm WARN npm WARN Could not resolve dependency: npm WARN peer [email protected]"^17.0.0" from [email protected] npm WARN node_modules/react-native-screens/node_modules/react-freeze npm WARN [email protected]"^1.0.0" from [email protected] npm WARN node_modules/react-native-screens npm WARN npm WARN Conflicting peer dependency: [email protected] npm WARN node_modules/react npm WARN peer [email protected]"^17.0.0" from [email protected] npm WARN node_modules/react-native-screens/node_modules/react-freeze npm WARN [email protected]"^1.0.0" from [email protected] npm WARN node_modules/react-native-screens

    Are there any plans to update to react 18?

    opened by henkean 1
  • How can I Tell if Freeze is Working?

    How can I Tell if Freeze is Working?

    I'm using React-Navigation v6 along with the latest version of react-native-screens and have followed the Quick Start Guide for React-Navigation... but how can I tell that it's actually doing anything? enableFreeze(true); seems to have zero effect on the app that I'm working on. I've been testing on Web (react-native-web) but haven't been able to confirm that it is even working.

    • I don't see any Freeze components in the component hierarchy using React Developer Tools in Chrome, running on Web via react-native-web.
    • I don't see any new Suspense-related components after enabling react-freeze.
    • react-native-screens doesn't seem to provide a freezeEnabled() method, like screensEnabled()...
    • I haven't noticed any change in performance when doing tasks like resizing the browser window with a navigation backstack of 10+ screens.

    Stepping into the enableFreeze call, I see:

    export function enableFreeze(shouldEnableReactFreeze = true) {// noop
    }
    

    How can I confirm whether react-freeze is actually working? I followed the documentation but it seems to no-op?

    I'm using react-native-screens 3.13.1.

    Thanks!

    opened by hbomatt 1
  • Maximum update depth exceeded

    Maximum update depth exceeded

    I'm getting this error since implementing react freeze. Can you think of any reason it may be responsible? (It's mentioned in the stack trace from Sentry). Posting in case react-freeze could be the cause somehow. Happened after doing many fast navigations.

    Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    
    This error is located at:
        in x
        in RCTView
        in Unknown
        in Unknown
        in v
        in RCTScrollContentView
        in RCTScrollView
        in i
        in ScrollView
        in q
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in r
        in Unknown
        in M
        in RCTView
        in Unknown
        in P
        in RCTModalHostView
        in o
        in le
        in w
        in RCTView
        in Unknown
        in Unknown
        in h
        in RNCSafeAreaView
        in _
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in o
        in Unknown
        in te
        in ve
        in xe
        in y
        in w
        in RCTView
        in Unknown
        in Unknown
        in m
        in RCTView
        in Unknown
        in Unknown
        in p
        in k
        in h
        in h
        in E
        in RCTView
        in Unknown
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in h
        in Suspense
        in v
        in E
        in RNSScreenStack
        in le
        in X
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in Y
        in h
        in Suspense
        in v
        in E
        in RNSScreenStack
        in le
        in Z
        in RCTView
        in Unknown
        in _
        in ee
        in Unknown
        in R
        in Unknown
        in _e
        in d
        in l
        in h
        in h
        in E
        in RCTView
        in Unknown
        in RCTView
        in Unknown
        in w
        in D
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in w
        in RNSScreenNavigationContainer
        in ve
        in g
        in RCTView
        in Unknown
        in _
        in V
        in Unknown
        in j
        in Unknown
        in P
        in ae
        in RCTView
        in Unknown
        in Unknown
        in q
        in v
        in t
        in s
        in a
        in RNCSafeAreaProvider
        in F
        in RCTView
        in Unknown
        in r
        in t
        in h
        in Unknown
        in _
        in $
        in Q
        in y
        in l
        in W
        in H
        in D
        in O
        in T
        in C
        in v
        in D
        in a
        in d
        in o
        in s
        in Unknown
        in t
        in g
        in RCTView
        in Unknown
        in g
        in E
        in Unknown
        in RCTView
        in Unknown
        in RCTView
        in Unknown
        in r
    {
    arguments: [
    Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    
    This error is located at:
        in x
        in RCTView
        in Unknown
        in Unknown
        in v
        in RCTScrollContentView
        in RCTScrollView
        in i
        in ScrollView
        in q
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in r
        in Unknown
        in M
        in RCTView
        in Unknown
        in P
        in RCTModalHostView
        in o
        in le
        in w
        in RCTView
        in Unknown
        in Unknown
        in h
        in RNCSafeAreaView
        in _
        in RCTView
        in Unknown
        in Unknown
        in RCTView
        in Unknown
        in Unknown
        in o
        in Unknown
        in te
        in ve
        in xe
        in y
        in w
        in RCTView
        in Unknown
        in Unknown
        in m
        in RCTView
        in Unknown
        in Unknown
        in p
        in k
        in h
        in h
        in E
        in RCTView
        in Unknown
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in h
        in Suspense
        in v
        in E
        in RNSScreenStack
        in le
        in X
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in Y
        in h
        in Suspense
        in v
        in E
        in RNSScreenStack
        in le
        in Z
        in RCTView
        in Unknown
        in _
        in ee
        in Unknown
        in R
        in Unknown
        in _e
        in d
        in l
        in h
        in h
        in E
        in RCTView
        in Unknown
        in RCTView
        in Unknown
        in w
        in D
        in RNSScreen
        in r
        in Unknown
        in h
        in Suspense
        in v
        in E
        in se
        in a
        in w
        in RNSScreenNavigationContainer
        in ve
        in g
        in RCTView
        in Unknown
        in _
        in V
        in Unknown
        in j
        in Unknown
        in P
        in ae
        in RCTView
        in Unknown
        in...
    ]
    }
    
    opened by nandorojo 0
  • Fix tests & setup CI

    Fix tests & setup CI

    This PR fixes unit test, eslint, and typescript configuration in the library.

    Also, this PR setups Github Actions to test code validity on every PR.

    Changes:

    • Fix (default -> named) import in index.test.tsx

    • Fix eslint error in index.tsx

    • Fix eslint to resolve typescript imports correctly

    • Bump type definitions to the newest versions

    • Add types to index.test.tsx

    • Add @typescript-eslint/parser and @typescript-eslint/eslint-plugin as dev dependencies

    • Add test:types script for checking typings

    • Setup Github Actions to run test scripts

    opened by kacperkapusciak 0
  • [React18] useLayoutEffect runs multiple times while using ReactDOMClient.createRoot

    [React18] useLayoutEffect runs multiple times while using ReactDOMClient.createRoot

    Problem

    useLayoutEffect runs multiple times while using ReactDOMClient.createRoot

    Open in StackBlitz

    test

    Reproduce Code

    import * as React from 'react';
    import { render } from 'react-dom';
    import { createRoot } from 'react-dom/client';
    import { Freeze } from 'react-freeze';
    
    const rootElement = document.getElementById('root')
    render(<App />, rootElement); // √
    createRoot(rootElement).render(<App />); // x
    
    function Test() {
      React.useLayoutEffect(() => {
        console.log('run useLayoutEffect'); // Log is executed for each unfreezing
      }, []);
    
      return <div>test</div>;
    }
    
    function App() {
      const [freeze, setFreeze] = React.useState(false);
    
      return (
        <div>
          <button onClick={() => setFreeze(!freeze)}>toggle freeze state</button>
          <Freeze freeze={freeze}>
            <Test />
          </Freeze>
        </div>
      );
    }
    
    opened by CJY0208 0
  • Does this library support Hermes

    Does this library support Hermes

    Sorry to bother, when I build Android on CircleCI(x86_64) and localmachine(M1) by fastlane and bundle. Both show the same error. But after I disable Hermes. The error goes away. Since the error points to react-freeze, so I ask it here. Thank you!

    npx react-native info info Fetching system and libraries information... System: OS: macOS 13.0 CPU: (8) arm64 Apple M1 Memory: 94.89 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.17.1 - ~/.nvm/versions/node/v16.17.1/bin/node Yarn: Not Found npm: 8.15.0 - ~/.nvm/versions/node/v16.17.1/bin/npm Watchman: 2022.10.17.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1 Android SDK: Not Found IDEs: Android Studio: Not Found Xcode: 14.1/14B5033e - /usr/bin/xcodebuild Languages: Java: 11.0.17 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: ^18.2.0 => 18.2.0 react-native: 0.70.5 => 0.70.5 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found

    `[07:59:28]: Picked up _JAVA_OPTIONS: -Xmx1500m myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:1769:18: warning: the variable "DebuggerInternal" was not declared in function "__shouldPauseOnThrow" typeof DebuggerInternal !== 'undefined' && DebuggerInternal.shouldPauseOnThrow === true ^~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:4994:7: warning: the variable "setTimeout" was not declared in function "logCapturedError" setTimeout(function () { ^~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:3592:21: warning: the variable "clearTimeout" was not declared in anonymous function " 90#" cancelTimeout = clearTimeout; ^~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:7492:30: warning: the variable "REACT_DEVTOOLS_GLOBAL_HOOK" was not declared in anonymous function " 90#" if ("undefined" !== typeof REACT_DEVTOOLS_GLOBAL_HOOK) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:7507:146: warning: the variable "nativeFabricUIManager" was not declared in anonymous function " 119#" null != handle._nativeTag && (null != handle._internalInstanceHandle ? (handle = handle._internalInstanceHandle.stateNode, null != handle && nativeFabricUIManager.dispatchCommand(handle.node, command, args)) : _$$_REQUIRE(_dependencyMap[2]).UIManager.dispatchViewManagerCommand(handle._nativeTag, command, args)); ^~~~~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:8324:5: warning: the variable "setImmediate" was not declared in function "handleResolved" setImmediate(function () { ^~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:8540:16: warning: the variable "AggregateError" was not declared in function "getAggregateError" if (typeof AggregateError === 'function') { ^~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11456:12: warning: the variable "fetch" was not declared in anonymous function " 294#" fetch: fetch, ^~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11457:14: warning: the variable "Headers" was not declared in anonymous function " 294#" Headers: Headers, ^~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11458:14: warning: the variable "Request" was not declared in anonymous function " 294#" Request: Request, ^~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11459:15: warning: the variable "Response" was not declared in anonymous function " 294#" Response: Response ^~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11608:24: warning: the variable "FileReader" was not declared in function "readBlobAsArrayBuffer" var reader = new FileReader(); ^~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11645:36: warning: the variable "Blob" was not declared in anonymous function " 305#" } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { ^~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11647:40: warning: the variable "FormData" was not declared in anonymous function " 305#" } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { ^~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11649:44: warning: the variable "URLSearchParams" was not declared in anonymous function " 305#" } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { ^~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11877:23: warning: the variable "XMLHttpRequest" was not declared in anonymous function " 314#" var xhr = new XMLHttpRequest(); ^~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:11468:76: warning: the variable "self" was not declared in anonymous function " 297#" var global = typeof globalThis !== 'undefined' && globalThis || typeof self !== 'undefined' && self || typeof global !== 'undefined' && global; ^~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:19082:27: warning: the variable "performance" was not declared in anonymous function " 498#" if ("object" === typeof performance && "function" === typeof performance.now) { ^~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:19105:26: warning: the variable "navigator" was not declared in anonymous function " 498#" "undefined" !== typeof navigator && undefined !== navigator.scheduling && undefined !== navigator.scheduling.isInputPending && navigator.scheduling.isInputPending.bind(navigator.scheduling); ^~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:19172:37: warning: the variable "MessageChannel" was not declared in anonymous function " 498#" };else if ("undefined" !== typeof MessageChannel) { ^~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:26733:32: warning: the variable "requestAnimationFrame" was not declared in function "onUpdate" this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); ^~~~~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:40700:16: warning: the variable "AbortController" was not declared in function "getAbortController" if (typeof AbortController === 'function') { ^~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:42699:34: warning: the variable "setInterval" was not declared in function "updateRefetchInterval" this.refetchIntervalId = setInterval(function () { ^~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:42723:11: warning: the variable "clearInterval" was not declared in function "clearRefetchInterval" clearInterval(this.refetchIntervalId); ^~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:47087:20: warning: the variable "cancelAnimationFrame" was not declared in function "schedule 2#" var cancel = cancelAnimationFrame; ^~~~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:77649:25: warning: the variable "Atomics" was not declared in anonymous function " 3494#" '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, ^~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:77650:24: warning: the variable "BigInt" was not declared in anonymous function " 3494#" '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, ^~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:77663:38: warning: the variable "FinalizationRegistry" was not declared in anonymous function " 3494#" '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, ^~~~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:77688:35: warning: the variable "SharedArrayBuffer" was not declared in anonymous function " 3494#" '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, ^~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:77702:25: warning: the variable "WeakRef" was not declared in anonymous function " 3494#" '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, ^~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:79302:51: warning: the variable "btoa" was not declared in function "dispatchXhrRequest" requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); ^~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:80283:7: warning: the variable "Buffer" was not declared in function "testForBuffer" Buffer.isBuffer({ ^~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100843:15: warning: the variable "util" was not declared in function "containsOnlyValidXChars" if (util.isNumberMatch(number, candidate.substring(index)) != MatchType.NSN_MATCH) { ^~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100843:73: warning: the variable "MatchType" was not declared in function "containsOnlyValidXChars" if (util.isNumberMatch(number, candidate.substring(index)) != MatchType.NSN_MATCH) { ^~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100870:11: warning: the variable "PhoneNumberUtil" was not declared in function "isNationalPrefixPresentIfRequired" if (PhoneNumberUtil.formattingRuleHasFirstGroupOnly(formatRule.getNationalPrefixFormattingRule())) { ^~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100891:69: warning: the variable "CountryCodeSource" was not declared in function "containsMoreThanOneSlashInNationalNumber" var candidateHasCountryCode = number.getCountryCodeSource() === CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN || number.getCountryCodeSource() === CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN; ^~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100898:31: warning: the variable "normalizeDigits" was not declared in function "checkNumberGroupingIsValid" var normalizedCandidate = normalizeDigits(candidate, true ^~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100906:28: warning: the variable "MetadataManager" was not declared in function "checkNumberGroupingIsValid" var alternateFormats = MetadataManager.getAlternateFormatsForCountry(number.getCountryCode()); ^~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100932:25: warning: the variable "formatNumber" was not declared in function "getNationalNumberGroups" var rfc3966Format = formatNumber(number, 'RFC3966', metadata); ^~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100943:53: warning: the variable "NON_DIGITS_PATTERN" was not declared in function "allNumberGroupsAreExactlyPresent" var candidateGroups = normalizedCandidate.split(NON_DIGITS_PATTERN); ^~~~~~~~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:100978:65: warning: the variable "Character" was not declared in function "allNumberGroupsRemainGrouped" if (util.getNddPrefixForRegion(region, true) != null && Character.isDigit(normalizedCandidate.charAt(fromIndex))) { ^~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:113863:14: warning: the variable "babelHelpers" was not declared in function "isSymbol 2#" return babelHelpers"typeof" === 'symbol'; ^~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:114514:20: warning: the variable "WebAssembly" was not declared in anonymous function " 5622#" wasm = new WebAssembly.Instance(new WebAssembly.Module( ^~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:136729:20: warning: the variable "localStorage" was not declared in function "ColorSchemeStore" if (typeof localStorage !== "undefined") { ^~~~~~~~~~~~ myapp/android/app/build/generated/assets/react/staging/release/index.android.bundle:142527:52: warning: the variable "FileList" was not declared in function "fe" if (de && (e instanceof Blob || e instanceof FileList) || !r && !i(e)) return e; ^~~~~~~~ myapp/node_modules/metro-source-map/node_modules/source-map/lib/source-map-generator.js:289 throw new Error('Invalid mapping: ' + JSON.stringify({ ^

    Error: Invalid mapping: {"generated":{"line":1,"column":702261},"source":"myapp/node_modules/react-freeze/src/index.tsx","original":{"line":37,"column":-1},"name":null} at SourceMapGenerator_validateMapping [as _validateMapping] (myapp/node_modules/metro-source-map/node_modules/source-map/lib/source-map-generator.js:289:13) at SourceMapGenerator_addMapping [as addMapping] (myapp/node_modules/metro-source-map/node_modules/source-map/lib/source-map-generator.js:101:12) at myapp/node_modules/metro-source-map/src/composeSourceMaps.js:41:15 at MappingsConsumer.eachMapping (myapp/node_modules/metro-source-map/src/Consumer/AbstractConsumer.js:36:16) at composeSourceMaps (myapp/node_modules/metro-source-map/src/composeSourceMaps.js:35:16) at Object. (myapp/node_modules/react-native/scripts/compose-source-maps.js:59:5) at Module._compile (node:internal/modules/cjs/loader:1126:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10) at Module.load (node:internal/modules/cjs/loader:1004:32) at Function.Module._load (node:internal/modules/cjs/loader:839:12)`

    opened by lucas-su-dev 0
  • Breaks KeyboardAvoidingView on previous screen

    Breaks KeyboardAvoidingView on previous screen

    Question

    Is there a way to enableFreeze globally, but disable it for certain screens?

    Issue

    If I enable freezing for a screen that has KeyboardAvoidingView, and then go back that screen while the keyboard is open, then the bottom of the screen gets weirdly cut off.

    enableFreeze(false) fixes it.

    Here are side-by-side videos:

    | enableFreeze(true) | enableFreeze(false) | | --------------------- | ---------------------- | |

    opened by nandorojo 4
  • How to implement this correctly?

    How to implement this correctly?

    If I add the code below into my index.js in react-native, is it going to work as intended for the screens which are deep in stack hierarchy?

    import { enableFreeze } from "react-native-screens";
    
    enableFreeze(true);
    

    Or do i need apply the usage below on every screen

    function SomeComponent({ shouldSuspendRendering }) {
      return (
        <Freeze freeze={shouldSuspendRendering}>
          <MyOtherComponent />
        </Freeze>
      );
    }
    
    opened by swizes 1
  • Invariant Violation: [4413,>"}]}] is not usable as a native method argument">

    Invariant Violation: [4413,"RCTView",{"transform":[{"scaleX":0},{"translateX":"<>"}]}] is not usable as a native method argument

    When enabling freeze, I get this error occasionally (maybe 1/10 navigations) when navigating screens in development mode on an android real device and simulator. Haven't tested on ios. Seems to not happen in production so far.

    "react-native-screens": "3.9.0"
    "@react-navigation/bottom-tabs": "^6.2.0"
    "@react-navigation/native": "^6.0.8"
    "@react-navigation/native-stack": "^6.5.0"
    "react-native": "0.65.1"
    

    Invariant Violation: [4413,"RCTView",{"transform":[{"scaleX":0},{"translateX":"<<NaN>>"}]}] is not usable as a native method argument

    opened by jslok 1
Owner
Software Mansion – Labs
Our experimental projects are hosted here. For our officially maintained libraries visit https://github.com/software-mansion.
Software Mansion – Labs
An upgradable boilerplate for Progressive web applications (PWA) with server side rendering, build with SEO in mind and achieving max page speed and optimized user experience.

React PWA v2 A highly scalable, Progressive Web Application foundation,boilerplate, with the best Developer Experience. Demo: https://demo.reactpwa.co

Atyantik 2.5k Dec 5, 2022
transform react class component to function component

react-class-to-fc ⭐ 特性 将react class组件转化为react 函数组件 ?? 安装 npm i react-class-to-fc -g ?? 使用 ctfc -i react-demo.js -o fc.js 就会将 react-demo.js文件中的class组

一口獠牙的小甜甜 50 Dec 1, 2022
A mobile-first React prototyping tool with React-Bootstrap component integration

A mobile-first React prototyping tool with React-Bootstrap component integration

OSLabs Beta 48 Apr 17, 2022
React Dev Inspector - jump to local IDE code directly from browser React component by just a simple click

React Dev Inspector Introduction This package allows users to jump to local IDE code directly from browser React component by just a simple click, whi

zthxxx 840 Dec 2, 2022
An extension that allows inspection of React component hierarchy in the Chrome and Firefox Developer Tools.

This project has migrated to github.com/facebook/react The source code for the v3 of the extension can be found in the v3 branch. To build the v3 brow

Facebook 11k Nov 29, 2022
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.4k Dec 5, 2022
Isolated React component development environment with a living style guide

Isolated React component development environment with a living style guide React Styleguidist is a component development environment with hot reloaded

Styleguidist 10.5k Dec 4, 2022
React JSON inspector component

React JSON Inspector Component React-based JSON inspector that features tree expansion and fast search. Live demo Installation npm install react-json-

Aziz Yuldoshev 291 Oct 13, 2022
Isolated React component development environment with a living style guide

Isolated React component development environment with a living style guide React Styleguidist is a component development environment with hot reloaded

Styleguidist 10.5k Dec 1, 2022
Isolated React component development environment with a living style guide

Isolated React component development environment with a living style guide React Styleguidist is a component development environment with hot reloaded

Vladimir Bezrukov 1 Oct 28, 2021
React component wrap for SimpleMDE Markdown Editor(v1.x)

react-simplemde-v1 React.js(v16.x+) component wrap for SimpleMDE Markdown Editor(v1.x+) Installation $ npm install --save simplemde react-simplemde-v1

Zhentian Lu 8 Dec 6, 2021
A flexible, responsive, and easy-to-use crossword component for React apps.

Install npm install --save @jaredreisinger/react-crossword # or # yarn add @jaredreisinger/react-crossword Usage See also the styleguidist docs for

Jared Reisinger 113 Nov 14, 2022
A component simplifies Goftino widget usage in your React application

@mohsen007/react-goftino A component simplifies Goftino widget usage in your React application Introduction This component applies to Goftino Web Widg

Mohsen Lotfi 6 Jun 6, 2022
A simple React Native date input component

react-native-datefield A simple React Native date input component Installation yarn add react-native-datefield or npm install react-native-datefield

tuantvk 10 Aug 12, 2022
An entity-component-system for React

React ECS react-ecs.ldlework.com A declarative Entity Component System for React. An ECS, or Entity Component System is a design pattern popular in si

Dustin Lacewell 74 Nov 20, 2022
A simple react component for adding a nice typewriter effect to your project.

React Simple Typewriter A simple react component for adding a nice typewriter effect to your project. Install npm npm i react-simple-typewriter Yarn y

Ahmed Khalil 70 Dec 5, 2022
React Fiber renderer and component container for Regl

React Regl React fiber renderer and custom container for regl Install Recommended: (react|react-dom) @ 17.x and regl @ 2.1.x. npm install @psychobolt/

Michael Tran 18 May 27, 2022
React Native component for Feather icons

React Native Feather Icons What is react-native-feather? react-native-feather is a collection of simply beautiful open source icons for React Native.

Yiğithan 14 Nov 23, 2022
A simple and fully customizable React Native component that implements an Image Slider UI.

react-native-image-slider-box Announce: All Pull-Requests have been applied. CI/CD has been integrated to update the package automatically. How to sen

Hamed 204 Nov 28, 2022