Home > Net >  Why is async await very slow?
Why is async await very slow?

Time:12-15

I want to make selector for the user to select name of section, and according to what he select, view the section types in another selector, then when he select the section type display the students in a table. I write code and get the data true but because i use (async..await) so the project get very slow and then closed. What's the wrong?

function Teacher() {
  const [data1, setData1] = useState([]);
  const [data2, setData2] = useState([]);
  const [data3, setData3] = useState([]);
  const [SectionName, setSectionName] = useState('بستان');
  const [Type, setType] = useState('أ');

  useEffect(() => {
    async function getName() {
      await Axios
        .get(`http://localhost:3003/getSectionsName`)
        .then(result => setData1(result.data));
    }
    getName()
  }, []);

  const nameSelector = (
    <select className="custom-select" onChange={(e) => {
      const selectedSectionName = e.target.value;
      setSectionName(selectedSectionName);
    }}>
      {data1.map((item) =>
        <option key={item.id} value={item.SectionName}>
          {item.SectionName}
        </option>
      )}
    </select>
  )

  async function typeSelector() {
    await Axios.put(`http://localhost:3003/getSectionTypes`, { SectionName: SectionName }).then(result => setData2(result.data))
  }

  const typeSelect = (
    typeSelector(),
    <select className="custom-select" onChange={(e) => {
      const selectedSectionType = e.target.value;
      setType(selectedSectionType);
    }}>
      {data2.map((item) =>
        <option key={item.id}>
          {item.Type}
        </option>
      )}
    </select>
  )

  function student() {
    Axios.put(`http://localhost:3003/getStudents`, { Type: Type, SectionName: SectionName }).then(result => setData3(result.data))
  }

  const studentTable = (
    student(),
    <table className="table" >
      <thead className="thead-dark">
        <tr>
          <th scope="col">الطلاب</th>
        </tr>
      </thead>
      <tbody>
        {data3.map(item => {
          return <tr key={item.Id}>
            <td>{item.FullName}</td>
          </tr>
        })}
      </tbody>
    </table>
  )
  return (
    <div className="container p-2">
      <h4> اختر الصف </h4>
        {nameSelector}
      <br />
      <h4> اختر الشعبة </h4>
        {typeSelect}
      <br /><br />
      <h4>
        {studentTable}
      </h4>
    </div>
  )
}

export default Teacher;

CodePudding user response:

  async function typeSelector() {
    await Axios.put(`http://localhost:3003/getSectionTypes`, { SectionName: SectionName }).then(result => setData2(result.data))
  }

  const typeSelect = (
    typeSelector(),
    ...

is plain wrong - it means you're calling typeSelector() with the comma sequencing operator as a side effect of rendering the component, and likely end up in an infinite render loop. This would happen with a non-async typeSelector() function too.

You will need to wrap those fetch calls within suitable useEffect() hooks, maybe like so (I took the liberty of also extracting the components into, well, components.)

function StudentTable({ students }) {
  return (
    <table className="table">
      <thead className="thead-dark">
        <tr>
          <th scope="col">الطلاب</th>
        </tr>
      </thead>
      <tbody>
        {students.map((item) => {
          return (
            <tr key={item.Id}>
              <td>{item.FullName}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

function NameSelector({ sections }) {
  return (
    <select
      className="custom-select"
      onChange={(e) => setSectionName(e.target.value)}
    >
      {sections.map((item) => (
        <option key={item.id} value={item.SectionName}>
          {item.SectionName}
        </option>
      ))}
    </select>
  );
}

function TypeSelect({ types }) {
  return (
    <select
      className="custom-select"
      onChange={(e) => setType(e.target.value)}
    >
      {types.map((item) => (
        <option key={item.id} value={item.id}>
          {item.Type}
        </option>
      ))}
    </select>
  );
}

function Teacher() {
  const [sections, setSections] = useState([]);
  const [types, setTypes] = useState([]);
  const [students, setStudents] = useState([]);
  const [sectionName, setSectionName] = useState("بستان");
  const [type, setType] = useState("أ");

  // Load sections on mount
  useEffect(() => {
    Axios.get(
      `http://localhost:3003/getSectionsName`,
    ).then((result) => setSections(result.data));
  }, []);
  // Load types based on selected section
  useEffect(() => {
    Axios.put(`http://localhost:3003/getSectionTypes`, {
      SectionName: sectionName,
    }).then((result) => setTypes(result.data));
  }, [sectionName]);
  // Load students based on section and type
  useEffect(() => {
    Axios.put(`http://localhost:3003/getStudents`, {
      Type: type,
      SectionName: sectionName,
    }).then((result) => setStudents(result.data));
  }, [sectionName, type]);

  return (
    <div className="container p-2">
      <h4> اختر الصف </h4>
      <NameSelector sections={sections} />
      <br />
      <h4> اختر الشعبة </h4>
      <TypeSelect types={types} />
      <br />
      <br />
      <h4>
        <StudentTable students={students} />
      </h4>
    </div>
  );
}

export default Teacher;

CodePudding user response:

Try useEffect() that has a dependency sectionName. When it changes, then you will call typeSelector() and student().

  const [data1, setData1] = useState([]);
  const [data2, setData2] = useState([]);
  const [data3, setData3] = useState([]);
  const [sectionName, setSectionName] = useState('بستان');

  const getName = async () => {
    const data = await Axios.get(`http://localhost:3003/getSectionsName`);
    setData1(data);
  };

  const typeSelector = async () => {
    const data = await Axios.put(`http://localhost:3003/getSectionTypes`, {
      SectionName: SectionName
    });
    setData2(data);
  };

  const student = async () => {
    const data = Axios.put(`http://localhost:3003/getStudents`, {
      Type: Type,
      SectionName: SectionName
    });
    setData3(data);
  };

  useEffect(() => {
    getName();
  }, []);

  useEffect(() => {
    typeSelector();
    student();
  }, [sectionName]);
  • Related