React asynchronous useState

Asked

Viewed 299 times

0

I’m new to React and I’m having a hard time filtering data that will be displayed in a table. I have the filter inputs (there are 5 in total) and a filter button that calls a function, in this function I have the setState that feeds the state that contains the information. The thing is, because it is asynchronous, useState only filters the data when I click the 'filter' button for the second time, how could I make this filter run immediately? Below an excerpt of the code:

 const [data, setData] = useState([]);  
 const [data_filter, setDataFilter] = useState([]);

 setData(data);
 setDataFilter(data); 

**Data variable contains all db data returned by Axios (get)

 function handleFiltro() {  
     if (numero) {  
       const p_filter = data_filter.filter(id => {  
         return id.id == numero;  
       });  
       setDataFilter(p_filter);  
     }    
     const data1 = data_filter.map(data => ({
       ...data,
       emissao: format(parseISO(data.createdAt), "d 'de' MMMM 'de' yyyy", {
         locale: pt,
       }),
       expiracao: format(parseISO(data.expire_at), "d 'de' MMMM 'de' yyyy", {
         locale: pt,
       }),
     }));


     setData(data1);
  }

  <button type="button" onClick={() => handleFiltro()}>
     <span>Filtrar</span>
  </button>
  • Inside your "handleFilter" function, try to do the setData this way: setData([...data1]);

  • I did the test and continues the same way, only works with 2 clicks on the filter button...

1 answer

0

The best way to solve this problem is with the useEffect hook, causing it to watch the data_filter state and only fire the setData after the update has been completed. Would look like this:

function handleFiltro() {  
  if (numero) {
    const p_filter = data_filter.filter(id => {  
      return id.id == numero;  
    });

    setDataFilter(p_filter);  
  }   
}    

useEffect(() => {
  const data1 = data_filter.map(data => ({
    ...data,
    emissao: format(parseISO(data.createdAt), "d 'de' MMMM 'de' yyyy", {
    locale: pt,
    }),
    expiracao: format(parseISO(data.expire_at), "d 'de' MMMM 'de' yyyy", {
    locale: pt,
    }),
  }));

  setData(data1);
}, [data_filter]);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.