skip to Main Content

I’m trying to load big JSON files in my app, all works perfectly on the web, but on android I get this message: Compiling JS failed: 624709:3354959:Invalid UTF-8 continuation byte Buffer size 160752371 starts with: …

What I did:
— Validate the JSON files
— Check for any no code characters in my files.
— Tried to load JSON files one by one (in an useeffect hook).

Error message (screenshot from my android emulator):
enter image description here

My component code:

import { useEffect, useState } from 'react';
import {
  Pressable,
  ScrollView,
  StyleSheet,
  useColorScheme,
} from 'react-native';

import HTMLView from 'react-native-htmlview';
import { useRecoilState } from 'recoil';

import baghawyJSON from '@/assets/tafaseer/baghawy.json';
import earabJSON from '@/assets/tafaseer/earab.json';
import katheerJSON from '@/assets/tafaseer/katheer.json';
import maanyJSON from '@/assets/tafaseer/maany.json';
import muyassarJSON from '@/assets/tafaseer/muyassar.json';
import qortobyJSON from '@/assets/tafaseer/qortoby.json';
import saadyJSON from '@/assets/tafaseer/saady.json';
import tabaryJSON from '@/assets/tafaseer/tabary.json';
import tanweerJSON from '@/assets/tafaseer/tanweer.json';
import waseetJSON from '@/assets/tafaseer/waseet.json';
import { Colors } from '@/constants';
import { tafseerTab } from '@/recoil/atoms';
import { TafseerAya, TafseerTabs } from '@/types';

import { ThemedText } from './ThemedText';
import { ThemedView } from './ThemedView';
import surahs from '../assets/quran-metadata/mushaf-elmadina-warsh-azrak/surah.json';

const tabLabels: Record<TafseerTabs, string> = {
  katheer: 'ابن كثير',
  maany: 'معاني القرآن',
  earab: 'إعراب القرآن',
  baghawy: 'البغوي',
  muyassar: 'الميسر',
  qortoby: 'القرطبي',
  tabary: 'الطبري',
  saady: 'السعدي',
  tanweer: 'التحرير و التنوير',
  waseet: 'الوسيط',
};

type Props = {
  aya: number;
  surah: number;
  opacity: number;
};
export default function Tafseer({ aya, surah, opacity }: Props) {
  const colorScheme = useColorScheme();
  const tintColor = Colors[colorScheme ?? 'light'].tint;
  const textColor = Colors[colorScheme ?? 'light'].text;
  const backgroundColor = Colors[colorScheme ?? 'light'].background;

  const [surahName, setSurahName] = useState<string>('');
  const [selectedTabValue, setSelectedTab] =
    useRecoilState<TafseerTabs>(tafseerTab);
  const [tafseerData, setTafseerData] = useState<TafseerAya[] | null>(null);

  const renderTafseerContent = (tafseer: TafseerAya[] | null): JSX.Element => {
    const ayaTafseer = tafseer?.find((t) => t.aya === aya && t.sura === surah);

    let tafseerText = 'لا يوجد تفسير.';
    if (!ayaTafseer?.text || ayaTafseer?.text === '<p></p>') {
      tafseerText = '<p>لا يوجد تفسير.</p>';
    } else {
      tafseerText = ayaTafseer?.text;
    }

    return (
      <ThemedView style={styles.tafseerContent}>
        <HTMLView
          value={tafseerText}
          stylesheet={{
            p: { color: textColor, fontFamily: 'Amiri_400Regular' },
          }}
        />
      </ThemedView>
    );
  };

  useEffect(() => {
    setSurahName(surahs[surah - 1]?.name ?? '');
  }, [surah]);

  useEffect(() => {
    switch (selectedTabValue) {
      case 'baghawy':
        setTafseerData(baghawyJSON as TafseerAya[]);
        break;
      case 'earab':
        setTafseerData(earabJSON as TafseerAya[]);
        break;
      case 'katheer':
        setTafseerData(katheerJSON as TafseerAya[]);
        break;
      case 'maany':
        setTafseerData(maanyJSON as TafseerAya[]);
        break;
      case 'muyassar':
        setTafseerData(muyassarJSON as TafseerAya[]);
        break;
      case 'qortoby':
        setTafseerData(qortobyJSON as TafseerAya[]);
        break;
      case 'saady':
        setTafseerData(saadyJSON as TafseerAya[]);
        break;
      case 'tabary':
        setTafseerData(tabaryJSON as TafseerAya[]);
        break;
      case 'tanweer':
        setTafseerData(tanweerJSON as TafseerAya[]);
        break;
      case 'waseet':
        setTafseerData(waseetJSON as TafseerAya[]);
        break;
      default:
        setTafseerData(katheerJSON as TafseerAya[]);
    }
  }, [selectedTabValue]);
  return (
    <ScrollView
      contentContainerStyle={[styles.scrollView, { backgroundColor, opacity }]}
    >
      <ThemedText style={styles.title}>
        {surahName} - الآية {aya}
      </ThemedText>
      <ThemedView style={styles.tabs}>
        {Object.keys(tabLabels).map((key) => {
          const tabKey = key as TafseerTabs;
          return (
            <Pressable
              key={tabKey}
              style={[
                styles.tabButton,
                selectedTabValue === tabKey && styles.activeTab,
                selectedTabValue === tabKey && { borderColor: tintColor },
              ]}
              onPress={() => setSelectedTab(tabKey)}
            >
              <ThemedText>{tabLabels[tabKey]}</ThemedText>
            </Pressable>
          );
        })}
      </ThemedView>
      {renderTafseerContent(tafseerData)}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scrollView: {
    padding: 20,
  },
  title: {
    fontSize: 18,
    marginBottom: 10,
  },
  tabs: {
    flexDirection: 'row',
    alignItems: 'center',
    flexWrap: 'wrap',
    gap: 2,
    justifyContent: 'flex-start',
  },
  tabButton: {
    paddingVertical: 10,
    paddingHorizontal: 15,
  },
  activeTab: {
    borderBottomWidth: 2,
  },
  tafseerContent: {
    marginBottom: 20,
    marginTop: 20,
  },
});

2

Answers


  1. Chosen as BEST ANSWER

    As @ushaikh said (thanks to him), the issue is related to the async load error, i resolved this issue by changing the code to:

    // useImageArray.ts hook
    export default function useImagesArray() {
      const [error, setError] = useState<string | null>(null);
      const [asset, setAsset] = useState<Asset | null>(null);
      const [isLoading, setIsLoading] = useState<boolean>(false);
      const { currentPage: page } = useCurrentPage();
      const isMounted = useRef(true);
    
      useEffect(() => {
        isMounted.current = true;
        setIsLoading(true);
    
        const loadAsset = async () => {
          try {
            const image = imagesMap[page];
            if (!image) throw new Error(`الصفحة ${page} غير موجودة`);
    
            const assetToLoad = Asset.fromModule(image);
            if (!assetToLoad.downloaded) {
              await assetToLoad.downloadAsync();
            }
            if (isMounted.current) {
              setAsset(assetToLoad); // Only set asset if mounted
            }
          } catch (error) {
            if (isMounted.current) {
              setError(
                error instanceof Error
                  ? error.message
                  : `الصفحة ${page} غير موجودة`,
              );
              setAsset(null);
            }
          } finally {
            if (isMounted.current) setIsLoading(false);
          }
        };
    
        loadAsset();
        return () => {
          isMounted.current = false; // Mark as unmounted
        };
      }, [page]);
    
      return { asset, isLoading, error };
    }
    
    //imagesMap constant
    export const imagesMap: Record<number, number> = {
      1: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/1.png'),
      2: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/2.png'),
      3: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/3.png'),
      4: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/4.png'),
      5: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/5.png'),
      6: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/6.png'),
      7: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/7.png'),
      8: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/8.png'),
      9: require('@/assets/mushaf-data/mushaf-elmadina-warsh-azrak/9.png'),
      ...
      }
    
    

  2. This related issue will happen due to the failure to handle the async operation properly.

    Click on more options for AVD devices, you will see this screen, and click on the bug report menu. It will start to collect bugs and give you a brief idea. Please let me know if it is helpful for you.
    enter image description here

    Here you can find more reasons for this failure
    compiling js failed react native expected buffer size

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search