How to turn the data we subscribed into a state? in functional component

how to set data to state in functional component ?

How to turn the data we subscribed into a state?

In case you refer to React, every update in the local state will refresh your DOM. You need some strategies to stop that from happening when you rely on subscriptions instead of methods. React.memo could be one way to do it.

In React you use effects. If your subscription data prop updates, you write it to the state.

import React, { useState } from 'react'

export default function YourComponent ({ dataProps } ) {
   const [dataInState, setDataInState] = useState([] /* or null */)

   useEffect(() => {
      if (conditions...)    {
         setDataInState(dataProps)
      }
   }, [your_dataProps_conditions])



   return (
      <div>Your view</div>
   )
}
1 Like

@paulishca
hi
i run this but i get Error .

this is my code :

   const [ChangeLogSate , ChangeLogSetState] = useState('');

    const {Data,DataLoading} = useTracker(() => {
        if (Roles.userIsInRole(Meteor.userId(), ['admin'])) {

            const noDataAvailable = { Data: '', DataLoading : false };
        
            const DataLoading  = Meteor.subscribe('Panel.Admin.Settings');
        
            if (!DataLoading.ready()) {
                return { ...noDataAvailable };
            }
        
            const Data =  Settings.findOne({_id:"1"});

            return {
                Data,
                DataLoading
            }; 
         
        }else{
            const noDataAvailable = { Data: '', DataLoading : '' };
            return { ...noDataAvailable };
        }
    });
   

    useEffect(() => {
        if(DataLoading){
            if(! ChangeLogSate){
                ChangeLogSetState(Data.ChangeLog)
            }
        }
      }, [DataLoading]);

but i get this Error :

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

throw in some console.log() in the effect and see how ofthen it runs. Looking at the logic a bit: if your data is loading, save the data… but your data is loading… Something sounds … not right.
Your condition should rather be something like … if no state or state !== new data or state … deep compare with the new data or state.length !== new data length or lastDataPull !== stateLastDataPull etc… I feel your conditions should be more logic-filled. Also, I prefer react data containers which help separata data operations from view/component.

@paulishca

    useEffect(() => {
        console.log('log');
      }, [DataLoading]);

Apparently logged twice.

@paulishca
I’re using react router ssr, could this be a problem?

What exactly do I need to do to execute this code only when the data is ready?

const DataLoading  = Meteor.subscribe('Panel.Admin.Settings');

Your condition if(DataLoading) always be true

@minhna So how should it be?

I think the problem is that it runs twice .
I also tried the following code.

   const {Data,DataLoading} = useTracker(() => {
        if (Roles.userIsInRole(Meteor.userId(), ['admin'])) {

            const noDataAvailable = { Data: '', DataLoading : '' };
        
            const subs  = Meteor.subscribe('Panel.Admin.Settings');
            const DataLoading =  subs.ready();
            if (!DataLoading) {
                return { ...noDataAvailable };
            }
        
            const Data =  Settings.findOne({_id:"1"});

            return {
                Data,
                DataLoading
            }; 
         
        }else{
            const noDataAvailable = { Data: '', DataLoading : '' };
            return { ...noDataAvailable };
        }
    });
   

 useEffect(() => {
        
        console.log(DataLoading);
      }, [DataLoading]);
     

It returns nothing once and returns true a second time

@filipenevola You do not have comfort?

you are missing dependencies [] in useTracker hook.

useTracker(() => {...}, [])

@ksinas
I did not understand exactly what you meant
But I tried the following code and got this error again.

 const {Data,DataLoading} = useTracker(() => {

        const noDataAvailable = { Data: '', DataLoading : '' };
    
        const subs  = Meteor.subscribe('Panel.Admin.Settings');
        const DataLoading =  subs.ready();
        if (!DataLoading) {
            return { ...noDataAvailable };
        }
    
        const Data =  Settings.findOne({_id:"1"});

        return {
            Data,
            DataLoading
        }; 
        
    },[]);

useEffect(() => {
        if(DataLoading == true){
            if(! ChangeLogSate && Data){
                ChangeLogSetState(Data);
            }
        }
        // console.log(DataLoading);
      }, [DataLoading]);
     

That was what just caught my eye, because if you don’t add dependencies, every render you will recreate data inside useTracker.

But if you see maximum update depth error, it’s probably something else in your component, not related to the tracker.