How do I read from a file?

  1. SDK Version: expo@41.0.1, expo-file-system@11.0.2
  2. Platforms(Android/iOS/web/all): Android/iOS

Sorry for the basic question. I am trying to just learn how to read and write information on the device. I have been able to save data to a file using writeAsStringAsync. But I’m having trouble figuring out where my invocation to read the file lives. I keep getting exceptions.

The current exception is

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

This error is located at:
    in App (created by ExpoRoot)
    in ExpoRoot (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
at node_modules/react-native/Libraries/Core/ReactFiberErrorDialog.js:43:2 in showErrorDialog
at [native code]:null in commitRootImpl
at [native code]:null in performSyncWorkOnRoot
at [native code]:null in <unknown>
at [native code]:null in forEach
at node_modules/react-native/Libraries/Core/setUpReactRefresh.js:43:6 in Refresh.performReactRefresh
at [native code]:null in callFunctionReturnFlushedQueue

Which I believe is because the app is querying the filesystem on like every render. But I only need to check the filesystem once on app startup, and then once every time I change state from there. Hopefully this is just a simple concept I don’t understand, with an easy fix that I can learn from.

Here is the main application, I removed everything that isn’t directly related to reading and writing. The key issue is with that first bit of code setSavedTask(getTask());

import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { TextInput } from 'react-native';
import { saveTask, getTask } from './TaskManagement';
import styles from './styles';

export default function App() {
  const [task, setTask] = React.useState("gello");
  const [savedTask, setSavedTask] = React.useState(null);

  setSavedTask(getTask());
  if (savedTask) {
    return (
      <View style={styles.container}>
        <Text style={styles.instructions}>
          Pulling text "{savedTask}" from file!
        </Text>
      </View>
    );
  }
  return (
    <View style={styles.container}>
      <Text style={styles.instructions}>
        The default word is {task}!
      </Text>
      <TextInput
        style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
        onChangeText={setTask}
        value={task}
        />
      <TouchableOpacity onPress={() => saveTask(task)} style={styles.button}>
          <Text style={styles.buttonText}>Save this word</Text>
      </TouchableOpacity>
    </View>
  );
}

And here is the TaskManagement file:

import * as FileSystem from 'expo-file-system';

const taskURI = FileSystem.documentDirectory + 'tasks.txt';

export async function saveTask(task: string) {
  try {
    await FileSystem.writeAsStringAsync(taskURI, task);
    console.log('Saved text:', task);
  } catch (e) {
    console.error("Couldn't save string:", task, e);
  }
}

export async function getTask() {
  try {
    const fileInfo = await FileSystem.getInfoAsync(taskURI);
    if(fileInfo.exists){
      let text = await FileSystem.readAsStringAsync(taskURI);
      console.log("Read text from file:",text);
      return text;
    } 
    else {
      return "";
    }
  } catch (e) {
    console.error("Couldn't read from file:", taskURI, e);
  }
}

I was mostly following along with that giphy example in the FileSystem docs, but I am having trouble finding any examples of code where someone just reads normal text.

Hey @draav, you’ll need to move your setSavedTask call out of the body of your App function as it will get called on every re-render. Move it into a useEffect to have it only run once when the app component is mounted if that’s the behavior you want.

Cheers,
Adam

1 Like

Sorry for the late response. Thanks so much for the answer.

I do not know the lifecycle of the app and didn’t know there was a trigger for when it is mounted, which I assume means startup. I will research more and try out your suggestion.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.