user826955
user826955

Reputation: 3206

Where to implement initialization code in react-native functional component

I am following the functional pattern as given by the expo project creation wizard, and I have a component like this:

Search.js

export default function Search() {
   const [searchResults, setSearchResults] = React.useState(buildContentViews(contents));

   return (
      <View style={styles.container}>
         <ScrollView contentContainerStyle={styles.contentContainer}>
            <View style={styles.statusLine}>
               <Text style={styles.statusLineText}>{(pageInfo.numResults || 0) + ' Treffer'}</Text>
            </View>
            {searchResults}
         </ScrollView>
      </View>
   );
}

Now I have some non-react-native implementation for backend REST-services, which shall regularly update the search results. Therefore I would need to do something like:

export default function Search() {
   const [searchResults, setSearchResults] = React.useState(buildContentViews(contents));

   client.events.on('searchResults', (results) => setSearchResults(results));

   return (
      <View style={styles.container}>
         <ScrollView contentContainerStyle={styles.contentContainer}>
            <View style={styles.statusLine}>
               <Text style={styles.statusLineText}>{(pageInfo.numResults || 0) + ' Treffer'}</Text>
            </View>
            {searchResults}
         </ScrollView>
      </View>
   );
}

However I quickly get the error that too many event listeners are established, which is probably because the above code gets run every time the component is (re-)rendered, or in other words, whenver the component is updated.

So how would I correctly register the event listener and/or deregister the event listener in this scenario?

Upvotes: 0

Views: 1157

Answers (1)

vitosorriso
vitosorriso

Reputation: 775

useEffect hook is your friend here!

This is how I handle registering/deregistering to a react-navigation event moving between the screens (I don't know how your client code works, this is just an example)

  useEffect(() => {
    const onFocus = () => {
      // here I do something when the screen gets focused
    }
    // this is how you handle the registration to the event
    const focusListener = navigation.addListener('didFocus', onFocus)

    // and this is how to handle deregistration!
    return () => focusListener.remove()

  }, []) // empty array of dependencies
  1. In the body of the useEffect hook, you define your actions;
  2. the return function is used to clean-up effects, the perfect place to remove an event listener;
  3. the empty array of dependencies assures you that this code will be executed just one time (after the first render) and no more! No more reallocation! The perfect way to define an event listener!

Upvotes: 2

Related Questions