Why is rendering occurring in a disorderly manner even using async / await?

Asked

Viewed 34 times

0

I’m using React and Typescript. The application aims to record schedules.

In the onChange() date selected by the user, call the function handleChangeData(), in it triggers the date update by setStateData(). In sequence I call another async function fetch() (I’ll describe your features below). After that, I execute through a setShowHorarios() the update of the variable showHorarios what use to control the display of times in rendering.

That function handleChangeData() is like this:

  function handleChangeData(e: React.ChangeEvent<HTMLInputElement>) {
    let data = e.target.value;
    
    setStateData(data);
    buscarHorarios(data);
    setShowHorarios(true);  
  }

In function fetch() I call two other functions also async, first to Search GendersNaData() that queries the bank via api and returns the reserved times on the received date as parameter. Then I call the second async function updateHorariosAvailable() that updates the schedules making unavailable those that are already booked. Following the transcription of the function fetch():

  async function buscarHorarios(data: string) {
    buscarAgendamentosNaData(data);
    atualizarHorariosDisponiveis();
  }

The async function Search GendersNaData() as I say, query via api the database, and is like this:

  async function buscarAgendamentosNaData(data: string) {
    const response = await api.get('agendamentos', {
      params: { 
        data_agend: data,
        organizacao_agend: state.organizacao_atd,
      }
    });
    setAgendamentosNaData(response.data); 
  }

Already the async updateHorariosAvailable(), traverses the array object by updating the object hours[] with the object of standard schedules to avoid working with junk from previous searches. Then in a map, check if there is already reservation of the read time, setting the property available="N" and performing the Return to update the element in the array object hours[]. So it is updateHorariosAvailable():

  async function atualizarHorariosDisponiveis() {
    horarios.map((horario, index) => {
      horario.disponivel = 'S'; 
      agendamentosNaData.map((agendamento: Agendamento) => { 
        if(horario.hora === agendamento.hora_agend) {
          horario.disponivel = 'N'; 
        }
        return horario;
      });
    });
  }

The array object hourly rates contains only the "time" and "available" property that are passed to an object seen as global, as follows (summarized):

const horariospadroes = [
  { hora: '08:00', disponivel: "S"},
  { hora: '08:30', disponivel: "S"},
  ...
  { hora: '17:00', disponivel: "S"},
  { hora: '17:30', disponivel: "S"}
]  

let horarios = horariospadroes;

It turns out that the rendered times are always displayed relative to a date previously selected. Example: If I select the date 07/11/2021 renders all times with my original vector, as per the above standard. If I change the date to 07/12/2021 renders the content of schedules, only it presents the data that should have been presented on the date selected before, which was 07/11/2021. And so on and so forth.

I believe it’s an execution out of order but I haven’t been able to identify the reasons.

How can this occur if the calls are always with async, async / await, ie first you should wait for the completion of a process to in sequence perform the following instructions?

This is the correct treatment for this situation? I couldn’t identify the problem. Can you please help me?

All help is welcome.

Below, I present to understand the "whole" in a summarized form the structure of the code as it is:

import React, { FormEvent, useEffect, useState } from 'react';
...

const horariospadroes = [
  { hora: '08:00', disponivel: "S"},
  { hora: '08:30', disponivel: "S"},
  ...
  { hora: '17:00', disponivel: "S"},
  { hora: '17:30', disponivel: "S"}
]  
let horarios = horariospadroes;

export interface Horario {
  hora: string;
  disponivel: string;
}

interface AtendimentoItemProps {  atendimento: Atendimento; }

export interface Agendamento {  ...omitido... }

const CadastroAgendamento: React.FC<AtendimentoItemProps> = ({atendimento}) => {
  const history = useHistory();  
  const { state } = useLocation<Atendimento>();
  const [showHorarios, setShowHorarios] = React.useState(false);  
  ...
  const [agendamentosNaData, setAgendamentosNaData] = useState([]); 

  // não sei porque, a primeira execução sempre retorna vazio, então força a primeira execução com data vazia
  useEffect(() => {
    buscarAgendamentosNaData('1900-01-01');
  }, []);

  useEffect(() => {
    buscarHorarios('1900-01-01');
  }, []);

  async function buscarHorarios(data: string) {
    buscarAgendamentosNaData(data);
    atualizarHorariosDisponiveis();
  }  

  async function buscarAgendamentosNaData(data: string) {
    const response = await api.get('agendamentos', {
      params: { 
        data_agend: data,
        organizacao_agend: state.organizacao_atd,
      }
    });
    setAgendamentosNaData(response.data); 
  }

  async function atualizarHorariosDisponiveis() {
    let horario = horariospadroes;
    horario.map((horario, index) => {
      agendamentosNaData.map((agendamento: Agendamento) => { 
        if(horario.hora === agendamento.hora_agend) {
          horario.disponivel = 'N'; 
        }
        return horario;
      });
    });
  }

  interface HorariosProps {...omitido...}

  const Horarios: React.FC<HorariosProps> = (props) => {
    let horarioRenderizado;
    if (props.disponivel==="S"){
      horarioRenderizado = 
        <div className="horario-item" style={{ color:"#FFFFFF" }} onClick={(e) => { setHoraAgend( props.hora ) }} >
          {props.hora}
        </div>;
    } else {
      horarioRenderizado = 
        <div style={{ color:"#FFFFFF", background:"#C7B7B7", cursor:"none", textDecoration:"line-through" }} className="horario-item" >
          {props.hora}
        </div>;
    }
  
    return(
      <div>
        { horarioRenderizado }
      </div>  
    );
  }
  
  function handleIncluirAgendamento(e: FormEvent ) { ... omitido ...  }

  function handleChangeData(e: React.ChangeEvent<HTMLInputElement>) {
    let data = e.target.value;
    setStateData(data);
    buscarHorarios(data);
    setShowHorarios(true); 
  }
    
  function ShowHorariosDisponiveis(props: any) {
    return(
      props.showHorarios ? 
      <div className="horario-container">
        {horarios.map((horario) => {
            return <Horarios hora={horario.hora} disponivel={horario.disponivel} />;
          })}
      </div> 
      : 
      null 
    );
  }

  return (
    <div id="cadastro-agendamento" className="container-cadastroagendamento">
      <Cabecalho />
      <main className="container-cadastroagendamento">
        <form onSubmit={handleIncluirAgendamento}>
          <fieldset className="container-form">

            <ShowHorariosDisponiveis showHorarios={showHorarios}/>

            <div className="input-block">
              <br></br>
              <ThemeProvider theme={theme}>
                <Button type="submit" variant="contained" color="primary" style={{ borderRadius: 50 }} className="botao" >
                  Confirmar
                </Button>
              </ThemeProvider>
            </div>

          </fieldset>
        </form>
      </main>
    </div>
  );
};

export default CadastroAgendamento;
  • has so async Function but, in your body has no await is already a problem about timing, every async function has something to be solved that needs to wait with await ... The code in general has problems and therefore errors and updates following unforeseen sequences

  • you know how to use async/await, your code apparently at some points does not need this resource!

  • These are my first steps with React, they could tell me where is wrong and some example of the correct way to use?

  • has many changes, I think I should first study, like atualizarHorariosDisponiveis do not need async ... in my view understood, I understand its beginning, but, need to study javascript first . Ok!

No answers

Browser other questions tagged

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