Reputation: 300
How can I make a custom hook in react that doesn't run immediately until I run it
For example:
const useHook = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState(undefined);
return [getData, { isLoading, data }];
};
function App() {
const [getData, { isLoading, data }] = useHook();
return <></>
}
const [UsingFC ,{props}] = useHook();
Like apollo graphql client useLazyQuery
Upvotes: 0
Views: 167
Reputation: 704
creating a custom hook in React that doesn't run immediately and instead run only when explicitly called you can use the concept of function references
import { useState, useRef } from 'react';
const useHook = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState(undefined);
const getData = useRef(() => {});
getData.current = () => {
setIsLoading(true);
setTimeout(() => {
setData(/* Your data here */);
setIsLoading(false);
}, 1000); // Replace this with your actual API call or data-fetching logic
};
return [getData, { isLoading, data }];
};
function App() {
const [getData, { isLoading, data }] = useHook();
return (
<>
<button onClick={getData.current}>Fetch Data</button>
</>
);
}
Upvotes: 1
Reputation: 850
If you don't want to execute some piece of code when the hook runs, your hook can return a function that wraps that code and which you can run on demand.
Upvotes: 0
Reputation: 4600
Basically nothing really interesting in implementation, you are just returning an array with a trigger method and data object.
const { useCallback, useState } = React;
const useHook = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState(undefined);
const getData = useCallback(() => {
setIsLoading(true);
// do your fetch or whatever
setTimeout(() => {
setData("data");
setIsLoading(false);
}, 1000);
}, []);
return [getData, { isLoading, data }];
};
function App() {
const [getData, { isLoading, data }] = useHook();
return (
<div className="App">
<p>IsLoading: {isLoading.toString()}</p>
<p>Data: {data}</p>
<button type="button" onClick={getData}>
Get
</button>
</div>
);
}
// v18.x+
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>
Upvotes: 2