Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Way to call hooks from button events in react

This is my first time to develop a react application. I intend to make an Api call when user clicked a button. Is it possible to directly call a hook from an event? If yes, how can I call it if the hook was from a different component?

This is the button (different component)

 const paginationButtons = (
    <React.Fragment>
      <Button onClick={() => viewDetails()}>View Details</Button>
    </React.Fragment>
  );

function viewDetails() {
   //Is it Possible to call fetch data.js and pass the url from here?
  }

This is the hook for fetch data.js

import axios from 'axios';
import PropTypes from 'prop-types';
import { useState, useEffect} from 'react';

const propTypes = {
  initialUrl: PropTypes.string.isRequired,
  initialParams: PropTypes.object
}

export const useFetchData = props => {
  PropTypes.checkPropTypes(propTypes, props, 'property', 'useFetchData');

  const { initialUrl, initialParams } = props;

  const [request, setRequest] = useState({
    url: initialUrl,
    params: initialParams
  });
  const [loading, setIsLoading] = useState(false);
  const [error, setError] = useState();
  const [data, setData] = useState([]);

  useEffect(() => {
    const {url, params} = request;

    const fetchData = async () => {
      setIsLoading(true);
      try {
        const result = await axios(url, {params: {...params}});
        setIsLoading(false);
        setData(result.data);
      } catch(err) {
        setIsLoading(false);
        setError(err);
      }
    }

    fetchData();
  }, [request]);

  const doFetch = (params) => {
    setRequest({url: request.url, params: params});
  };
  return {loading, error, data, doFetch};
}

Thank you very much for your help.

like image 784
Dan Avatar asked May 27 '19 02:05

Dan


People also ask

How do you call a function in react event handler?

React Event Handlers. In React, the onClick handler allows you to call a function and perform an action when an element is clicked. onClick is the cornerstone of any React app. Click on any of the examples below to see code snippets and common uses: Call a Function After Clicking a Button. Call an Inline Function in an onClick Event Handler.

How do I use onClick event in react?

With React, it's a little bit different, and a lot easier. On a button, we can access the onClick JSX attribute, which does the exact same thing as the addEventListener function for the click event mentioned above. We can also define a handleClick function, and call it in the onClick attribute of the button.

What are react hooks?

Hooks don’t replace your knowledge of React concepts. Instead, Hooks provide a more direct API to the React concepts you already know: props, state, context, refs, and lifecycle. As we will show later, Hooks also offer a new powerful way to combine them.

How do I listen to DOM Events in react?

Listening to DOM events in React can be a little tricky and can quickly get messy. Even worse, it can be hard to trigger effects and state updates based on DOM events. Luckily, we can easily use custom hooks to 'reactify' our DOM event listeners. Read on! To get started, you're going to need a (surprise...) React app.


1 Answers

What you intend to do is possible, but in my opinion, it shouldn't be done in a real-world application. Here's why.

First, let's consider why we would want to use a hook. React function components had no way of preserving local state and handling lifecycle events between rerenders. This is why hooks were introduced.

Before I use a hook, I would ask myself, "Do I need to handle component state or the component life-cycle?". If not, using a hook is either overkill or an anti-pattern.

In your example, let's consider what you may be trying to do with the viewDetails function. Obviously, you want to do the fetch call, but what do you intend to do afterward? Let's see some possibilities...

  1. Update the dom imperatively: You shouldn't do imperative operations unless there is a very specific reason. Let's assume, you want to show an alert, then, of course, you can call an imperative API (like notie.js or sweet-alert for instance).
  2. Update the dom reactively: This is the most common scenario I think. In such a case, you should either call some setState function, or fire an event to be captured by another component. In either case, there's no use of using a hook for fetching data.

Thus instead of trying to call a hook like useFetchData, you should call a function like doFetchData.

I am not suggesting that you should get rid of the useFetchData hook. It's just, they serve different purposes. It makes sense to use the hook for any fetch operations that should happen at load time rather than as a response to a user action.


Now that I have given my opinion, here's one way you can trigger a hook based on user action.

// Here we are using a shouldFetch flag to conditionally call a function
function useFetch(url, options, shouldFetch, setShouldFetch) {
    const [state, setState] = useState({});
    useEffect(() => {
        if (shouldFetch) {
            doFetch(url, options)
                // set the fetch result to local state
                .then(data => {
                   setState(data)
                   setShouldFetch(false) // avoid infinite calls
                }) 
        }
    });

    return [state]; // You can maybe add fetch status as well
}

Now you can use it like this,

function MyComponent() {
    const [shouldFetch, setShouldFetch] = useState(false);
    const [fetchData] = useFetch('url', {}, shouldFetch, setShouldFetch);

    return (
        <Button onClick={() => {setShouldFetch(true)}}>Click Me</Button>
    )
}

But really, you shouldn't use a hook this way. A regular doFetchData call is the way to go. Call some setState functions to preserve the fetched data if you need to.

like image 50
Pubudu Dodangoda Avatar answered Sep 20 '22 00:09

Pubudu Dodangoda