necolas / react-native-web

Cross-platform React UI packages
https://necolas.github.io/react-native-web
MIT License
21.46k stars 1.77k forks source link

fix(Image): keep function identiy accross renders #2638

Open Gregoirevda opened 5 months ago

Gregoirevda commented 5 months ago

Description

Currently when an inline function is passed to the Image or Animated.Image component, the useEffect will be triggered on every render, causing the image the be fetched on every render.

props accepting a function and declared in the dependency array are: onLoad onLoadEnd onLoadStart onLoadError. It shouldn't be up to the developer to pass a memoized function.

The browser will cache subsequent image fetches (not sure about all platforms), so as it may seem acceptable setting the cache key to reload will fetch the image on every render.

Example

function App() {
  const Component = Image || Animated.Image;

  // Not memoized, causing the fetch on every render
  function bad() {}

  const good = useCallback(() => {}, [])

  return <Component source={{uri}} onLoadEnd={bad} onLoad={() => { /* equally bad */ }} onLoadStart={good)  />
}
codesandbox-ci[bot] commented 5 months ago

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 9e05b48a20c10da24934bc94f76c24fee8cb0615:

Sandbox Source
react-native-web-examples Configuration
Gregoirevda commented 1 month ago

@necolas Does the fix make sense? I didn't know where to put the utility method so added in vendor to get feedback, but tell me where the right place is please