Reputation: 21
I want to update the props of several component rendered by a tracker (by using useTracker), to update the front without refreshing the page.
Here's a simple example of my problem :
My collection is ValuesCollection with 1 attribute by default (myValue) : { "myValue" : "defaultValue", "key" : "uniqKey"}
In the backend, a batch change this value to another value (take 10 sec per batch)
import { useTracker } from "meteor/react-meteor-data";
import { ValuesCollection } from "api/MongoAPI";
export default function MyPage() {
const { values } = useTracker(() => {
Meteor.subscribe("values", {});
const values = ValuesCollection.find({}).fetch();
return { values };
});
return (
<Stack spacing={2}>
{values.map((elem) => (
<ValueComponent key={elem.key} myProps={elem.myValue}/>
))}
</Stack>
)
}
When i load the page with 5 object in ValuesCollection, i have
<Stack spacing={2}>
<ValueComponent key=1 myProps="defaultValue"/>
<ValueComponent key=2 myProps="defaultValue"/>
<ValueComponent key=3 myProps="defaultValue"/>
<ValueComponent key=4 myProps="defaultValue"/>
<ValueComponent key=5 myProps="defaultValue"/>
</Stack>
After 10 seconds, my first object is updated in database, with myValue="first". My tracker values is updated, but my ValueComponent doesn't re render. So, nothing happen on my front page.
<Stack spacing={2}>
{/* Here, i want
<ValueComponent key=1 myProps="first"/>
*/}
<ValueComponent key=1 myProps="defaultValue"/>
<ValueComponent key=2 myProps="defaultValue"/>
<ValueComponent key=3 myProps="defaultValue"/>
<ValueComponent key=4 myProps="defaultValue"/>
<ValueComponent key=5 myProps="defaultValue"/>
</Stack>
How can I do to update my component as the collection updates to display the results in live ?
Upvotes: 0
Views: 135
Reputation: 91
The usage of useTracker
seems fine. And if you have tested that values
actually changes, then it also works fine (as Hugo Mallet suggests in the comments).
I think two suspects are in place:
MyProp
prop inside your ValueComponent
key
prop, it is possible you're assigning "undefined" as the key for all the items. Weird stuff happens when you mess with the keys. Do you get a warning in the console saying you have duplicate keys in your example? In such case you could could change the key={elem.key}
with key={elem._id}
to fix it up.A debugging suggestion that would address both: log both key
and MyProp
inside your ValueComponent
and see what you get.
Also, sharing the code of your ValueComponent would help.
Upvotes: 1
Reputation: 644
In order to refresh a React component you need to update the local state or the props. None of this is happening in your component. This is why in React you have mainly two options (and a third which I use in all my projects)
For a simple case like yours, separating data from the view would be the easiest thing to do and solution 2 is the easiest to implement. If you need to do this in a large project, 1 or 3 would be your best options.
Ok there could be another way. In your tracker function include a state update. You don't need to use it further, just to update it.
e.g.
const [lastUpdate, setLastUpdate] = React.useState(null)
//....
useTracker(() => {
Meteor.subscribe("values", {});
const values = ValuesCollection.find({}).fetch();
return { values };
setLastUpdate(Date.new())
})
Upvotes: 1