0

I have two components rendering different UI based on user type. Both components have nearly 50% similar logic of fetching data from api, connecting to store.

I tried, reusing the login by creating custom hook.

const { products, loading} = useFetchProducts(userId);

and now I can define a useFetchProducts reducer

  const useFetchProducts= (userId) => {
   const [ loading, setLoading ] = useState(false);
   const [ products, setProducts ] = useState(null);

   useEffect(() => {
       setLoading(true);
         fetchUserProducts(userId).then((res) => {
           setLoading(false);
           setProducts(res.data);  
     }); 
   }, [])
 }

How do I return products and loading state to my component from this reducer to hide or show a loader as well as to show list of products,

4
  • you can pass the props in other component through import in parent class Commented Jun 12, 2019 at 10:04
  • My question here is this, how to get state of loader in the component where I a using this custom hook. How to pass state from custom hook to component? Commented Jun 12, 2019 at 10:06
  • you can import spinner component in parent class, then setState and pass the state value in spinner component as a props through custom hooks Commented Jun 12, 2019 at 10:19
  • useEffect(() => { setLoading(true); fetchUserProducts(userId).then((res) => { setLoading(false); setProducts(res.data); }); }, []) render(){ return ( // pass here hooks state value <spinner value={hooks state value} /> Commented Jun 12, 2019 at 10:20

2 Answers 2

3

You simply need to return the values from the custom hook.

const useFetchProducts= (userId) => {
   const [ loading, setLoading ] = useState(false);
   const [ products, setProducts ] = useState(null);

   useEffect(() => {
       setLoading(true);
         fetchUserProducts(userId).then((res) => {
           setLoading(false);
           setProducts(res.data);  
     }); 
   }, [])
   return {loading, products}
 }

It will work because when the data is available it will cause a re-render and due to that, the component in which you use the custom hook will re-render causingthe update

Sign up to request clarification or add additional context in comments.

1 Comment

yes thanks , this makes somesense now. I will try this out now.
1

You need to return value from your custom hook.

const useFetchProducts= (userId) => {
   const [ loading, setLoading ] = useState(false);
   const [ products, setProducts ] = useState(false);

   useEffect(() => {
       setLoading(true);
         fetchUserProducts(userId).then((res) => {
           setLoading(false);
           setProducts(res.data);  
     }); 
   }, [])
   return { products, loading }
 }

2 Comments

How can you be sure it will only return data once useEffect finishes its call. I don't think this will work.this will only return { products: false, loading: false}
It will return updated data in each render. your useEffect will cause re-render when you set products and loading values. so in next render you will get updated loading and products.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.