React-native-fast-image: How to determine if preload completed

Created on 27 Mar 2019  路  9Comments  路  Source: DylanVann/react-native-fast-image

I am creating a quiz app in which I need to pre download 50 small images (5MB in total) used in 50 questions. I want to start quiz only when all images are downloaded , is there any way to know e.g. some kind of onComplete method ?

Most helpful comment

This feature is the only thing stopping us from finally replacing react-native-cached-image. Is this feature planned for a future release @DylanVann ?

All 9 comments

See #437,
I am also waiting for it!

I tried #437 on android, its working really nice :)

This feature is the only thing stopping us from finally replacing react-native-cached-image. Is this feature planned for a future release @DylanVann ?

Any update on this?

Sorry for unnecessary comment, but this would be a great feature. Any update?

I've been hopefully anticipating this feature for over a year now. There's some unfortunate off-putting visual behavior in the apps where i use react-native-fast-image because of it.

At this point i'd happily pay someone to have a PR with this feature merged. DM me if interested.

+1

Hi everyone, I've been waiting for this feature for quite some time too.
I tried developing it myself but was unable to actually run this project on my machine

So I came up with a work around, a Component.

It receives the uris and a onLoad callback as props:

// PreloadImages.tsx
import React, { Fragment, useEffect } from 'react'
import FastImage from 'react-native-fast-image'

import useCounter from '../hooks/useCounter'

const TIMEOUT = 1000 * 30 // 30 seconds

interface Props {
  onLoad?: (result: 'error' | 'timeout' | 'success') => void
  uris: string[]
  disableTimeout?: boolean
  retryOnError?: boolean
}
const PreloadImages: React.FC<Props> = ({
  onLoad,
  uris,
  disableTimeout,
  retryOnError,
}) => {
  const [attempt, { increment: incrementAttempt }] = useCounter(1, [
    JSON.stringify(uris),
  ])
  const [loadedCount, { increment }] = useCounter(0, [
    JSON.stringify(uris),
    attempt,
  ])

  useEffect(() => {
    const timeout = setTimeout(() => {
      if (!disableTimeout && onLoad) {
        onLoad('timeout')
      }
    }, TIMEOUT)

    if (loadedCount === uris.length) {
      clearTimeout(timeout)
      if (onLoad) {
        onLoad('success')
      }
    }

    return () => {
      clearTimeout(timeout)
    }
  }, [loadedCount, JSON.stringify(uris)])

  const onError = () => {
    if (retryOnError) {
      incrementAttempt()
      return
    }

    if (onLoad) {
      onLoad('error')
    }
  }

  return (
    <Fragment>
      {uris.map(uri => (
        <FastImage
          key={`${uri}#${attempt}`}
          source={{ uri, priority: 'high' }}
          onLoadEnd={increment}
          onError={onError}
          style={{ width: 0, height: 0 }}
        />
      ))}
    </Fragment>
  )
}

export default PreloadImages

// useCounter.ts
import { useEffect, useReducer } from 'react'

type Action =
  | { type: 'increment' }
  | { type: 'decrement' }
  | { type: 'set'; value: number }

function reducer(state: number, action: Action) {
  switch (action.type) {
    case 'increment':
      return state + 1
    case 'decrement':
      return state - 1
    case 'set':
      return action.value
  }
}

type CounterHook = [
  number,
  {
    increment: () => void
    decrement: () => void
  }
]
const useCounter = (initialCount: number, deps?: unknown[]): CounterHook => {
  const [state, dispatch] = useReducer(reducer, initialCount)

  useEffect(() => {
    dispatch({ type: 'set', value: initialCount })
  }, deps)

  return [
    state,
    {
      increment: () => dispatch({ type: 'increment' }),
      decrement: () => dispatch({ type: 'decrement' }),
    },
  ]
}

export default useCounter

Thanks for the quick-fix @vieiraluca, really appreciate it.

For such an essential feature to go ignored for over two years really doesn't instill a lot of confidence in this repos future. Especially so as effort has been put in by the community for literal years while receiving near as makes no difference, zero feedback or collaboration from @DylanVann.

While i understand that @DylanVann has full ownership of this repo and he's allowed to do as he pleases, it's infuriating to see this absolute neglect. I wish @DylanVann would reconsider adding maintainers, or finally giving this 4.7K starred repo the attention it deserves.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jslok picture jslok  路  3Comments

mschipperheyn picture mschipperheyn  路  3Comments

baba43 picture baba43  路  3Comments

Doko-Demo-Doa picture Doko-Demo-Doa  路  3Comments

Aligertor picture Aligertor  路  3Comments