0

I am trying to call useEffect() whenever arrayWithDeeplyNestedObjects changes. export default compose(... is part of an offline first database (watermelonDB) and updates arrayWithDeeplyNestedObjects when there is a change in the database. One could expect useEffect() to execute, whenever arrayWithDeeplyNestedObjects changes, but it is not. This is beause useEffect() only performs a shallo comparison and does not recognize the changes in arrayWithDeeplyNestedObjects.

import withObservables from '@nozbe/with-observables';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import {compose} from 'recompose';
import {Q} from '@nozbe/watermelondb';

const Foo = ({arrayWithDeeplyNestedObjects}) => {
  console.log('render'); // <-- this renders whenever arrayWithDeeplyNestedObjects is updated

  useEffect(() => {
    console.log(new Date()); // <-- this does not render whenever arrayWithDeeplyNestedObjects is updated
    const doSomething = async () => {
        ...
    };
    const data = await doSomething();
    setData(data);
  }, [arrayWithDeeplyNestedObjects]); // <-- this does only perform a shallow compare

    return <SomeNiceUi />
}

export default compose(
  withDatabase,
  withObservables(['arrayWithDeeplyNestedObjects'], ({database}) => ({
    arrayWithDeeplyNestedObjects: database.get(SOME_TABLE).query().observe(),
  })),
)(Foo); <-- subscription das fires everytime an update is made to the database

This is how arrayWithDeeplyNestedObjects looks like

[{"__changes": null, "_isEditing": false, "_preparedState": null, "_raw": {"_changed": "x,y", "_status": "created", "id": "3", "x": 5851, "id_arr": "[\"160\"]", "id": "6wmwep5xwfzj3dav", "y": 0.17576194444444446}, "_subscribers": [], "collection": {"_cache": [RecordCache], "_subscribers": [Array], "changes": [Subject], "database": [Database], "modelClass": [Function SomeTable]}}]

The changes to arrayWithDeeplyNestedObjects are done in the objects either to x, y or id_arr. The length of arrayWithDeeplyNestedObjects can change as well. There might be more (or less) objects of the same structure in there.

How to call useEffect() everytime arrayWithDeeplyNestedObjects changes?

four-eyes
  • 10,740
  • 29
  • 111
  • 220
  • 1
    Why do you need the useEffect? If the `console.log('render')` is run when you expect, then that's the right place to invoke `doSomething`, no? – jme11 Jan 12 '23 at 21:01
  • @jme11 How would I `await` the result of `doSomething()` when doing it where `console.log('render')` is currently? – four-eyes Jan 13 '23 at 10:47
  • I'm not sure can answer that because `doSomething()` is too abstract. A more concrete example or explanation may help. – jme11 Jan 13 '23 at 21:43
  • @jme11 Do Something process the data coming from the database. – four-eyes Jan 14 '23 at 07:24

1 Answers1

0

try this:

useEffect(() => {
  console.log(new Date());
  const doSomething = async () => {
    ...
  };
  doSomething();
}, [JSON.stringify(arrayWithDeeplyNestedObjects)]);
rachel
  • 11
  • 4