React JS call function with paramiters on button click

57 Views Asked by At

this is the question, I've a button on page, on button click I would call a function for fetch a data from REST API. This is the code:

import React from 'react';
//import Navigatore  from './componente_1.js';
import { Table } from 'react-bootstrap';
import base from './global.js';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import {  useEffect, useState } from 'react';
import moment from 'moment';
import {Button} from 'react-bootstrap';


const Appuntamenti  = () => {
  const [dati, setDati] = useState([]); 
 

  function useCaricamento (giorno)  {
    //Appuntamenti/getByData?data=2024-02-27
    useEffect(()=>{
      fetch(base+'Appuntamenti/getByData?data=' + giorno)
      .then((response)=> response.json())
      .then((datos) => {
        setDati(datos); 
      });
    });
  }
  var contenuto;
  if(dati.length === 0) {
    contenuto = <tr><td colSpan='5'>Dati non caricati</td></tr>;
  } else {
    contenuto = dati.map((elem) => {
      return(
        <tr>
          <td>{elem.cliente.cognome}</td>
          <td>{elem.cliente.nome}</td>
          <td>{elem.variante.nome}</td>
          <td width={120}>{moment(elem.data_ora_inizio).format("HH:mm")} - {moment(elem.data_ora_fine).format("HH:mm")}</td>
        </tr>
      );
    })
  }
  useCaricamento("2024-02-27");

  function Bottoni (props) {
    const {ricarica} = useCaricamento(props.data);
    return(
        <Button variant="primary" >{props.testo}</Button>
      
    );
  }
  
  
  
  return (
      
       
      <div  id='contenitore'>
       <Bottoni  data={moment().add(1, "day").format("YYYY-MM-DD")} testo="Domani"></Bottoni>
       <Bottoni  data={moment().format("YYYY-MM-DD")} testo="Oggi"></Bottoni>
        <Table  striped bordered hover size='sm' >
            <thead>
              <tr>
                <th>Cognome</th>
                <th>Nome</th>
                <th>Tratt.</th>
                <th>Ora</th>
              </tr>
            </thead>
            <tbody>
            {contenuto}
            </tbody>
          </Table>
        
      </div>
   
  );
}

export default Appuntamenti;

In this version of code, I've made a custom Component (Bottoni) that call a function "useCaricamento" for fetching data. Now the error is useCaricamento(...) is undefined But even i link the call to onclick event directly, the problem change to React Hook "useCaricamento" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks

I'm new of react, i dont undestand what i'm wrong.

1

There are 1 best solutions below

3
YUSOF KHAN On BEST ANSWER

Problems in Your Code:

  1. Misuse of useEffect within useCaricamento.
  2. Calling Hooks from Regular Functions.

How to fix the problems:

  1. Refactor useCaricamento to be a regular function.
  2. Use onClick Handler in Bottoni Component.

The fixed code:

import React, { useState } from 'react';
import { Button, Table } from 'react-bootstrap';
import moment from 'moment';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import base from './global.js';

const Appuntamenti = () => {
  const [dati, setDati] = useState([]);

  // Async function for fetching data
  const caricamento = async (giorno) => {
    try {
      const response = await fetch(base + 'Appuntamenti/getByData?data=' + giorno);
      const datos = await response.json();
      setDati(datos);
    } catch (error) {
      console.error("Failed to fetch data:", error);
    }
  };

  // Function to render table rows
  const renderContent = () => {
    if (dati.length === 0) {
      return <tr><td colSpan='5'>Dati non caricati</td></tr>;
    } else {
      return dati.map((elem, index) => (
        <tr key={index}> {/* Use a more unique key if available */}
          <td>{elem.cliente.cognome}</td>
          <td>{elem.cliente.nome}</td>
          <td>{elem.variante.nome}</td>
          <td width={120}>{moment(elem.data_ora_inizio).format("HH:mm")} - {moment(elem.data_ora_fine).format("HH:mm")}</td>
        </tr>
      ));
    }
  };

  // Button component with click handler
  const Bottoni = ({ data, testo }) => {
    return (
      <Button variant="primary" onClick={() => caricamento(data)}>
        {testo}
      </Button>
    );
  };

  return (
    <div id='contenitore'>
      <Bottoni data={moment().add(1, "days").format("YYYY-MM-DD")} testo="Domani" />
      <Bottoni data={moment().format("YYYY-MM-DD")} testo="Oggi" />
      <Table striped bordered hover size='sm'>
        <thead>
          <tr>
            <th>Cognome</th>
            <th>Nome</th>
            <th>Tratt.</th>
            <th>Ora</th>
          </tr>
        </thead>
        <tbody>
          {renderContent()}
        </tbody>
      </Table>
    </div>
  );
}

export default Appuntamenti;