midhun k
midhun k

Reputation: 576

React redux -how to get data in each components after the api response written in Reducer

am new to redux and react.

I have just gone through some redux tutorial and started to implement some sue cases .. And one use case i really want is i need a state that i should get in all components,so thats possible with redux as globalized state.

I have a scenario,an api call and i should get this api response in all my components using redux. But thats not happening.

I have index.js as

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { createStore } from "redux";
import allReducer from "./reducers";
import { Provider } from "react-redux";

import "./styles.css";


let store = createStore(
  allReducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

My reducer as

var userArray = [];
fetch("https://jsonplaceholder.typicode.com/users")
  .then(res => res.json())
  .then(
    result => {
      console.log(result);
      userArray = result;
    },

    error => {}
  );

const IsLoggedReducer = (state, action) => {
  console.log(userArray);
  switch (action.type) {
    case "SIGNIN":
      return (state = userArray);
    case "LOGGEDOUT":
      return (state = userArray);
    default:
      return (state = userArray);
  }
};
export default IsLoggedReducer;

and my app.js as

import React from "react";
import { useSelector } from "react-redux";

function App() {
  const counter1 = useSelector(state => state.counterReducer);
  const isLogged = useSelector(state => state.IsLoggedReducer);

  return (
    <h1>
      This {counter1}
      <ul>
        {isLogged.length > 0
          ? isLogged.map(item => {
              return <li key={item.id}>{item.name}</li>;
            })
          : "No data"}
      </ul>
    </h1>
  );
}

export default App;

when initial load its coming as null array and when i make some edit t the component and save ,it gets data and gets populated..

Here is the code https://codesandbox.io/embed/quirky-sunset-s95gu?fontsize=14

Any help is much appreciated

Upvotes: 0

Views: 1408

Answers (2)

Misol Goh
Misol Goh

Reputation: 1223

I hope this simple codes for action and reducer can help you understand react-redux.

For action,

export const signin = (userArray) => {
  return {
    type: "SIGNIN",
    payload: userArray,
  };
};

export const loggedout = (userArray = []) => {
  // You can do something for making users logged out here using userArray and return changed value using payload
  // Or just return [] as payload because it's logged out
  return {
    type: "LOGGEDOUT"
    payload: userArray,
  };
};

export const initiate = (userArray) => {
  return {
    type: "INITIATE",
    payload: userArray,
  }
}

For reducer, please consider reducer as changer of state.

const IsLoggedReducer = (state = initialState, action) => {
  switch (action.type) {
    case "SIGNIN":
      return action.payload;
    case "LOGGEDOUT":
      return action.payload;
    case "INITIATE":
      return action.payload;
    default:
      return state;
  }
};

When it comes to calling api, I want to recommend to use redux-saga or redux-thunk but if you need calling api just one time at the beginning of the component. You may be able to use useEffect(https://reactjs.org/docs/hooks-effect.html) as componentDidMount is used for calling api in a class component.

And I hope this useEffect code can help you get the feeling

import { useSelector, useDispatch } from 'react-redux';
import { initiate } from 'actions';

function main () {
  const state = useSelector((state) => state.user);
  const dispatch = useDispatch();
  const onInit = useCallback((data) => dispatch(initiate(data), [dispatch]);

  useEffect(() => {
    // call api and get response
    const userArray = fetch();

    onInit(userArray);
  }, []);

  return (<div>...</div>);
}

Upvotes: 1

ibtsam
ibtsam

Reputation: 1710

Ok you are not doing some things in a right way

1 - As API calling is an asynchronous task so you need to handle it, I would recommend write some action creator which does this API calling for you, and when you get the response from API then dispatch appropriate action to update the store state.

2- In your reducer you are mutating the state, don't mutate the previous state, instead return new state object from previous state

Hope it helps

Upvotes: 0

Related Questions