npm install redux redux-saga react-redux axios

 

export const FETCH_USER_REQUEST = "FETCH_USER_REQUEST";

export const FETCH_USER_SUCCESS = "FETCH_USER_SUCCESS";

export const FETCH_USER_FAILURE = "FETCH_USER_FAILURE";

 

export const fetchUserRequest = () => ({

  type: FETCH_USER_REQUEST,

});

 

export const fetchUserSuccess = (user) => ({

  type: FETCH_USER_SUCCESS,

  payload: user,

});

 

export const fetchUserFailure = (error) => ({

  type: FETCH_USER_FAILURE,

  payload: error,

});

 

import { FETCH_USER_REQUEST, FETCH_USER_SUCCESS, FETCH_USER_FAILURE } from "./actions";

 

const initialState = {

  loading: false,

  user: null,

  error: null,

};

 

const userReducer = (state = initialState, action) => {

  switch (action.type) {

    case FETCH_USER_REQUEST:

      return { ...state, loading: true };

    case FETCH_USER_SUCCESS:

      return { loading: false, user: action.payload, error: null };

    case FETCH_USER_FAILURE:

      return { loading: false, user: null, error: action.payload };

    default:

      return state;

  }

};

 

export default userReducer;



import { takeLatest, call, put } from "redux-saga/effects";

import axios from "axios";

import { FETCH_USER_REQUEST, fetchUserSuccess, fetchUserFailure } from "./actions";

 

// API Call

const fetchUserApi = () => axios.get("https://jsonplaceholder.typicode.com/users/1");

 

// Worker Saga: Handles API Call

function* fetchUserSaga() {

  try {

    const response = yield call(fetchUserApi);

    yield put(fetchUserSuccess(response.data));

  } catch (error) {

    yield put(fetchUserFailure(error.message));

  }

}

 

// Watcher Saga: Listens for Actions

export function* watchUserSaga() {

  yield takeLatest(FETCH_USER_REQUEST, fetchUserSaga);

}

 

import { createStore, applyMiddleware } from "redux";

import createSagaMiddleware from "redux-saga";

import userReducer from "./reducer";

import { watchUserSaga } from "./sagas";

 

// Create Saga Middleware

const sagaMiddleware = createSagaMiddleware();

 

// Create Store

const store = createStore(userReducer, applyMiddleware(sagaMiddleware));

 

// Run Saga

sagaMiddleware.run(watchUserSaga);

 

export default store;

 

import React from "react";

import { useSelector, useDispatch } from "react-redux";

import { fetchUserRequest } from "./actions";

 

const App = () => {

  const dispatch = useDispatch();

  const { loading, user, error } = useSelector((state) => state);

 

  return (

    <div>

      <h1>Redux-Saga Example</h1>

      <button onClick={() => dispatch(fetchUserRequest())}>

        {loading ? "Loading..." : "Fetch User"}

      </button>

      {user && <p>Name: {user.name}</p>}

      {error && <p style={{ color: "red" }}>Error: {error}</p>}

    </div>

  );

};

 

export default App;

 

import React from "react";

import ReactDOM from "react-dom";

import { Provider } from "react-redux";

import store from "./store";

import App from "./App";

 

ReactDOM.render(

  <Provider store={store}>

    <App />

  </Provider>,

  document.getElementById("root")

);

 

import { all } from "redux-saga/effects";

import { watchUserSaga } from "./sagas";

import { watchOtherSaga } from "./otherSaga";

 

export default function* rootSaga() {

  yield all([watchUserSaga(), watchOtherSaga()]);

}

 

import { eventChannel } from "redux-saga";

import { take, put } from "redux-saga/effects";

 

// Create Event Channel for WebSocket

function createWebSocketChannel(socket) {

  return eventChannel((emit) => {

    socket.on("message", (data) => {

      emit({ type: "NEW_MESSAGE", payload: data });

    });

    return () => socket.close();

  });

}

 

// Saga to Handle WebSocket Messages

function* watchWebSocket(socket) {

  const channel = yield call(createWebSocketChannel, socket);

  while (true) {

    const action = yield take(channel);

    yield put(action);

  }

}