Skip to content

Commit 5cc120d

Browse files
Mohammad Hunan ChughtaiMohammad Hunan Chughtainathan-contino-mongo
authored
(DOCSP-15010): Using Change Listeners In Your Components - React Native SDK (#996)
* (DOCSP-15010): Reacting to changes from components * removed unneeded text * update * add instructions to class components * separated react content from react-to-changes * added rn files to its own examples folder under node + excluded them from jest suite * fix file names * added generated files * Add emphasize lines * re-add class component * re-add functional component * fix toc tree * update wording * fix grammar * updated title to avoid gerunds * fix typo our->your * replace {+realm+} objects with {+service-short+} objects * fix wording * update * removed redudant class component example * Update source/sdk/react-native/examples/react-to-changes.txt Co-authored-by: nate contino <[email protected]> * fix spacing * fixed Reactjs -> React.js * update wording * typo fix * update wording * switched component name * add example directive * fix example paragraph * fix wording and grammar * fix grammar * fix typo * Update source/sdk/react-native/examples/use-change-listeners-in-components.txt Co-authored-by: nate contino <[email protected]> * Update source/sdk/react-native/examples/use-change-listeners-in-components.txt Co-authored-by: nate contino <[email protected]> * Update source/sdk/react-native/examples/use-change-listeners-in-components.txt Co-authored-by: nate contino <[email protected]> * added emphasize to non-generated file Co-authored-by: Mohammad Hunan Chughtai <[email protected]> Co-authored-by: nate contino <[email protected]>
1 parent d0ddf8a commit 5cc120d

File tree

6 files changed

+188
-19
lines changed

6 files changed

+188
-19
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, {useEffect, useState} from 'react';
2+
import {Text} from 'react-native';
3+
import Realm from 'realm';
4+
// :code-block-start: using-change-listeners-functional-component
5+
const TaskList = () => {
6+
const [tasks, setTasks] = useState([]);
7+
// :emphasize-start:
8+
useEffect(() => {
9+
// :emphasize-end:
10+
Realm.open({
11+
schema: [TaskSchema], // predefined schema
12+
}).then(realm => {
13+
14+
const tasks = realm.objects('Task');
15+
// set state to the initial value of your realm objects
16+
setTasks([...tasks]);
17+
18+
// :emphasize-start:
19+
tasks.addListener(() => {
20+
// update state of tasks to the updated value
21+
setTasks([...tasks]);
22+
});
23+
// :emphasize-end:
24+
25+
realm.write(() => {
26+
// the following tasks will trigger the change listener and update the UI
27+
realm.create('Task', {
28+
name: 'Go to the grocery store',
29+
});
30+
realm.create('Task', {
31+
name: 'Exercise in the gym',
32+
});
33+
});
34+
35+
// cleanup function
36+
// :emphasize-start:
37+
return () => {
38+
const tasks = realm.objects('Task');
39+
// Remember to remove the listener when you're done!
40+
tasks.removeAllListeners();
41+
// :emphasize-end:
42+
// Call the close() method when done with a realm instance to avoid memory leaks.
43+
realm.close();
44+
};
45+
});
46+
}, []);
47+
48+
return (
49+
<>
50+
{tasks.map(task => (
51+
<Text key={task.name}>{task.name}</Text>
52+
))}
53+
</>
54+
);
55+
};
56+
// :code-block-end:
57+
export default TaskList;

examples/node/jest.config.js

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,21 @@ module.exports = {
66
projects: [
77
{
88
displayName: "JavaScript",
9-
moduleFileExtensions: ['js'],
10-
testMatch: [
11-
"<rootDir>/Examples/**/*.js",
12-
],
13-
setupFilesAfterEnv: [
14-
'<rootDir>/testSetup.js',
15-
],
9+
moduleFileExtensions: ["js"],
10+
testMatch: ["<rootDir>/Examples/**/*.js"],
11+
setupFilesAfterEnv: ["<rootDir>/testSetup.js"],
12+
modulePathIgnorePatterns: ["<rootDir>/Examples/rn"],
1613
},
1714
{
1815
displayName: "TypeScript",
19-
moduleFileExtensions: ['ts', 'js'],
20-
preset: 'ts-jest/presets/js-with-ts',
21-
setupFilesAfterEnv: [
22-
'<rootDir>/testSetup.js',
23-
],
24-
testMatch: [
25-
"<rootDir>/Examples/**/*.ts",
26-
],
27-
"transform": {
28-
"^.+\\.ts$": "ts-jest"
16+
moduleFileExtensions: ["ts", "js"],
17+
preset: "ts-jest/presets/js-with-ts",
18+
setupFilesAfterEnv: ["<rootDir>/testSetup.js"],
19+
modulePathIgnorePatterns: ["<rootDir>/Examples/rn"],
20+
testMatch: ["<rootDir>/Examples/**/*.ts"],
21+
transform: {
22+
"^.+\\.ts$": "ts-jest",
2923
},
3024
},
31-
]
25+
],
3226
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.. code-block:: javascript
2+
:emphasize-lines: 3, 12-15, 28-31
3+
4+
const TaskList = () => {
5+
const [tasks, setTasks] = useState([]);
6+
useEffect(() => {
7+
Realm.open({
8+
schema: [TaskSchema], // predefined schema
9+
}).then(realm => {
10+
11+
const tasks = realm.objects('Task');
12+
// set state to the initial value of your realm objects
13+
setTasks([...tasks]);
14+
15+
tasks.addListener(() => {
16+
// update state of tasks to the updated value
17+
setTasks([...tasks]);
18+
});
19+
20+
realm.write(() => {
21+
// the following tasks will trigger the change listener and update the UI
22+
realm.create('Task', {
23+
name: 'Go to the grocery store',
24+
});
25+
realm.create('Task', {
26+
name: 'Exercise in the gym',
27+
});
28+
});
29+
30+
// cleanup function
31+
return () => {
32+
const tasks = realm.objects('Task');
33+
// Remember to remove the listener when you're done!
34+
tasks.removeAllListeners();
35+
// Call the close() method when done with a realm instance to avoid memory leaks.
36+
realm.close();
37+
};
38+
});
39+
}, []);
40+
41+
return (
42+
<>
43+
{tasks.map(task => (
44+
<Text key={task.name}>{task.name}</Text>
45+
))}
46+
</>
47+
);
48+
};

source/sdk/react-native/examples.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Usage Examples - React Native SDK
1010
Open & Close a Local Realm </sdk/react-native/examples/open-and-close-a-local-realm>
1111
Read & Write Data </sdk/react-native/examples/read-and-write-data>
1212
React to Changes </sdk/react-native/examples/react-to-changes>
13+
Use Change Listeners In Components </sdk/react-native/examples/use-change-listeners-in-components>
1314
Modify an Object Schema </sdk/react-native/examples/modify-an-object-schema>
1415
Connect to a MongoDB Realm Backend App </sdk/react-native/examples/connect-to-mongodb-realm-backend-app>
1516
Authenticate Users </sdk/react-native/examples/authenticate-users>
@@ -26,6 +27,7 @@ Realm-Database (Non-Sync)
2627
- :doc:`Open & Close a Local Realm </sdk/react-native/examples/open-and-close-a-local-realm>`
2728
- :doc:`Read & Write Data </sdk/react-native/examples/read-and-write-data>`
2829
- :doc:`React to Changes </sdk/react-native/examples/react-to-changes>`
30+
- :doc:`Use Change Listeners In Components </sdk/react-native/examples/use-change-listeners-in-components>`
2931
- :doc:`Modify an Object Schema </sdk/react-native/examples/modify-an-object-schema>`
3032

3133
Application Services (Sync)

source/sdk/react-native/examples/react-to-changes.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,9 @@ call the instance's ``removeAllListeners()`` function:
8989
- :js-sdk:`Realm.Object.removeAllListeners() <Realm.Object.html#removeAllListeners>`
9090

9191
.. literalinclude:: /examples/generated/node/react-to-changes.codeblock.react-to-changes-remove-all-listeners.js
92-
:language: javascript
92+
:language: javascript
93+
94+
Registering and Removing Listeners From Your React Components
95+
-------------------------------------------------------------
96+
To learn how to register and remove listeners within your application, check out
97+
the documentation on how to :ref:`use change listeners in React components <react-native-use-listeners-in-components>`.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
.. _react-native-use-listeners-in-components:
2+
3+
=====================================================
4+
Use Change Listeners In Components - React Native SDK
5+
=====================================================
6+
7+
.. default-domain:: mongodb
8+
9+
.. contents:: On this page
10+
:local:
11+
:backlinks: none
12+
:depth: 2
13+
:class: singlecol
14+
15+
16+
Overview
17+
--------
18+
You can copy your {+service-short+} objects to your component's :reactjs:`state
19+
<docs/state-and-lifecycle.html>`. However, since {+service-short+} objects are
20+
live and automatically update in response to changes, you must update the copies
21+
of them to prevent your UI from drifting out of date with underlying data. You can do this by
22+
registering a :ref:`change listener <react-native-change-notifications>` in your
23+
component and updating the state variable when that listener fires.
24+
25+
.. warning::
26+
27+
Failing to update copies of {+service-short+} objects leads to out-of-date data displayed
28+
in your UI as objects are deleted or changed.
29+
30+
Procedure
31+
~~~~~~~~~
32+
To keep your UI up-to-date with changes to underlying {+service-short+} objects,
33+
declare a state variable for your {+service-short+} objects using the
34+
:reactjs:`useState() <docs/hooks-state.html>` hook.
35+
36+
Within the :reactjs:`useEffect() <docs/hooks-effect.html>` hook, set the state variable to
37+
the initial value of your objects. Then declare a change listener on the
38+
{+service-short+} objects.
39+
40+
Finally, return an anonymous cleanup function that you can use to remove the
41+
change listener and close the {+service-short+}. React.js will call this cleanup function when
42+
the component unmounts.
43+
44+
.. example::
45+
46+
In the following example, a developer creates an application to manage
47+
tasks. Within a ``TaskList`` component, define a state variable called
48+
``tasks``. The developer wants to display the initial list of tasks already
49+
saved in the database after the component mounts. To do this, they :ref:`open
50+
a realm <react-native-open-a-local-realm>` within a ``useEffect`` function and
51+
then set the ``tasks`` state variable to the initial value of the ``tasks``
52+
stored in the {+service-short+}.
53+
54+
The developer registers a change listener to update the state variable when
55+
changes to the ``tasks`` have been made in the {+client-database+}. The
56+
developer then creates some additional tasks.
57+
58+
Once the component unmounts, the developer wants to unregister the change
59+
listener. To do this, they return a cleanup function and call ``task.removeAllListeners()``.
60+
Finally they :ref:`close the realm <react-native-close-a-realm>`.
61+
62+
.. include:: /examples/generated/rn/using-change-listeners-functional-component.codeblock.using-change-listeners-functional-component.js.code-block.rst
63+

0 commit comments

Comments
 (0)