Abstracting async hooks out from components A component displays a list of values and I'm trying to hide everything about how those values are gotten, essentially divorcing concerns about state away from the component itself so that in the future any changes to which API data is fetched from, what store is used, etc won't effect the component.
First, is this a good idea at all or should mount/unmount actions be handled directly in the component?
Second, if it is a good approach, how is my implementation? I'm feeling comfortable in JS but am not an expert
ContentList.js:
import React from 'react'

import './ContentList.css'

import { ContentCardContainer } from '../ContentCard/ContentCard'
import { getPostSummaries } from '../../Utils/ContentAPI'

import { Grid } from '@material-ui/core'

export function ContentListContainer(props) {
  const posts = getPostSummaries()

  return &lt;ContentList posts={posts} /&gt;
}

function ContentList(props) {
  return  (
    &lt;div className='content-list'&gt;
      &lt;Grid container &gt;
        {props.posts.map((post, id) =&gt; 
          &lt;Grid item xs={12} sm={12} lg={6}&gt;
            &lt;ContentCardContainer 
              key={id} 
              id={id} 
              title={post.title} 
              summary={post.summary} 
              link={'post/' + post.title} 
            /&gt;
          &lt;/Grid&gt;
        )}
      &lt;/Grid&gt;
    &lt;/div&gt;
  )
}

ContentApi.js:
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { setContent, setSummaries } from '../Store/Actions'
import axios from 'axios'

const apiRoot = '/api'

export const getPostByID = (id) =&gt; {    
    const dispatch = useDispatch()
   
    useEffect(() =&gt; {
      axios.get(apiRoot+'/post', {params: {id}})
        .then(resp =&gt; dispatch(setContent(resp.data.content)))
        .catch(() =&gt; dispatch(setContent('')))
      
        return () =&gt; dispatch(setContent(''))
    }, [])

    return useSelector(state =&gt; state.content)
}

export const getPostSummaries = () =&gt; {
  const dispatch = useDispatch()

  useEffect(() =&gt; {
    axios.get(apiRoot+'/post-summaries')
      .then(resp =&gt; dispatch(setSummaries(resp.data.posts)))
      .catch(() =&gt; dispatch(setSummaries([])) )
  }, [])

  return useSelector(state =&gt; state.summaries)
}
The general approach looks just fine. The logic behind data retrieval isn't entirely related to the rendering of components, so putting it into a custom hook instead makes good sense, especially if other components might need the data as well.
A few suggestions:

React recommends that the function names of custom hooks start with use, to clearly indicate that it's a hook and that other hooks (like useEffect) can be used inside it.
If other components might need to use the summaries as well, or if this component may get completely unmounted and then re-mounted again, consider whether you can use the summaries that were retrieved previously instead of fetching them again. (Or maybe you do want to fetch them again regardless - think about what you want.)
There doesn't really appear to be error handling, other than setSummaries([]). It would be more user friendly to indicate to the user if there's an error (and, at least in the development environment, to log the error).
Having both a ContentListContainer and a ContentList seems odd, since ContentListContainer is empty except for the custom hook call. If you aren't planning to add more stuff to the container, consider removing ContentListContainer entirely and putting the hook call into ContentList instead.