0

Developing a React Native application for Android, I am totally stuck with a problem concerning the database Realm.

The app enables a user to query a prepopulated database via search bar. For example, you type a name such as "John" and a query to the database is performed, returning all persons with name "John".

Currently, the Realm database is initiated on every render, which is not performant at all:

import ...

const SearchBar = props => {
  let [inputValue, setInputValue] = useState(null);

  const sendInputValueToReduxStore = text => {
    setInputValue(text);
    props.setInputValueSearchBar(text);
  };

  const peopleSchema = {
    name: 'realm',
    properties: {
      name: 'string?',
      color: 'string?',
    },
  };

  let realm = new Realm({
    path: fs.DocumentDirectoryPath + '/default.realm',
    schema: [peopleSchema],
    readOnly: true,
  });

  const people = realm.objects('realm');
  let resultArray = [];

  const databaseRequest = () => {
    const query = inputValue;
    const result = inputValue
      ? people.filtered("name == '" + query + "'")
      : 'default';
    resultArray = Array.from(result);
    return resultArray.map(oneGuy => (
      <Text className="oneGuy" key={oneGuy.name}>
        {oneGuy.name}
      </Text>
    ));
  };

  const isText = props.text;

  return (
    <View>
      <Header searchBar rounded>
        <Item>
          <Icon name="ios-search" />
          <Input
            placeholder="Search"
            onChangeText={text => sendInputValueToReduxStore(text)}
            value={inputValue}
          />
        </Item>
      </Header>
      {isText && (
        <View>
          <Text>{props.text}</Text>
        </View>
      )}
      <View>{databaseRequest()}</View>
    </View>
  );
};   

export default SearchBar;

So, I would like to put these parts:

  const peopleSchema = {
    name: 'realm',
    properties: {
      name: 'string?',
      color: 'string?',
    },
  };

  let realm = new Realm({
    path: fs.DocumentDirectoryPath + '/default.realm',
    schema: [peopleSchema],
    readOnly: true,
  });

... into a useEffect()-Hook with empty dependency array to create the Realm database only one time on the first render. But when I do so, React complains that "assignments to the realm variable will be lost after each render".

enter image description here

But I think this wouldn't be much of a problem, since I only want to open and query the database.

I read about using the useRef()-Hook to solve the problem above, but I am wondering if my whole approach makes sense at all (opening the database just once). Would it be better to just leave the component above as is and without caring for it's lifecycle phases?

RuntimeError
  • 1,332
  • 4
  • 23
  • 41

1 Answers1

0

Well, you can pass an empty array as a second argument, to tell React that your effect doesn't depend on any values from props or state, so it never needs to re-run.

useEffect(() => {

    /* your code */

}, []); // run an effect and clean it up only once (on mount and unmount)
OO7
  • 660
  • 4
  • 10
  • That was my idea too, like I pointed out in my post. But unfortunately, it gives an error: " ... But when I do so, React complains that "assignments to the realm variable will be lost after each render" ..." – RuntimeError Feb 10 '20 at 10:15