da45
da45

Reputation: 381

React new HOOKS api, useReducer with dynamic initialState

In case we want to fetch data from remote server and then pass it as initial state to a reducer, how we can proceed ? I tried to call dispatch inside useEffect but it was rejected as per rule of calling hooks inside useEffect(...) is forbidden,

Any help ?

Upvotes: 3

Views: 5534

Answers (1)

Jemi Salo
Jemi Salo

Reputation: 3751

The only way you can pass the data as the initial state to a reducer is to fetch the data before rendering your component. You can do that in the parent:

const Parent = () => {
  const [data, setData] = useState(null)

  useEffect(() => {
    apiCall().then(response => {
      setData(response.data)
    })
  }, [])

  if (!data) return null
  return <MyComponent data={data} />
}

const MyComponent = ({ data }) => {
  const [state, dispatch] = useReducer(reducer, data)
  ... // utilize state
}

.

The above approach is undesirable as it breaks separation of concerns. Usually it is better to set a null initial state and call dispatch to change it to the desired state:

const MyComponent () => {
  const [state, dispatch] = useReducer(reducer, null)

  useEffect(() => {
    apiCall().then(response => {
      dispatch({
        type: 'INITIALIZE',
        data: response.data
      })
    })
  }, [])

  if (!state) return null
  ... // utilize state
}

.

Upvotes: 7

Related Questions