Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle side effects when migrating from Redux to React Context API + hooks

If you have a Redux Application which you'd like to migrate to the new React Context API + hooks (useReducer) how would you replace redux-saga or redux-thunk for handling side effects? Let's take the example from redux-saga's github page:

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

What is the recommended best practice for doing the equivalent without Redux, but using the React Context api + hooks instead?

like image 830
Dac0d3r Avatar asked Apr 03 '19 17:04

Dac0d3r


Video Answer


1 Answers

Take a look at useEffect hook. This is what you use for side-effects.

https://reactjs.org/docs/hooks-effect.html

Here is an example of how to call an api from your component and render the data:

import ReactDOM from "react-dom";
import React, { useState, useEffect } from "react";
import axios from "axios";

function SearchResults() {
  const [data, setData] = useState(null);
  useEffect(() => {
    function getFetchUrl() {
      return "https://hn.algolia.com/api/v1/search?query=react";
    }
    async function fetchData() {
      console.log("asdasd");
      const result = await axios(getFetchUrl());
      setData(result.data);
    }

    fetchData();
  }, []);
  return <div>{JSON.stringify(data)}</div>;
}

ReactDOM.render(<SearchResults />, document.getElementById("root"));

I partially took this code from overreacted.io, I strongly suggest you read this amazing article about useEffect hook: https://overreacted.io/a-complete-guide-to-useeffect/

Regarding useReducer, it's basically a useState on steroids. It allows you to handle more complex state operations, but there isn't a big difference really.

In the case you want state to be shared by different components, you may use useContext but its really unrelated on how the side-effects work.

---- about redux:

I just want to comment also that moving to use React Context api + hooks to replace redux in your app could be good if you just use it for passing data to nested components, for example. But if you want all the great tooling, middleware, devtools, etc, Redux is still a great choice, even with hooks, they are not mutually exclusive.

See:

https://blog.isquaredsoftware.com/2019/03/presentation-state-of-redux/ Specifically https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/10 https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/11

like image 111
Luciano Semerini Avatar answered Sep 19 '22 22:09

Luciano Semerini