1

I am working on a project and I need to fetch data from backend or from an API. I tried fetch the data but nothing appears. I think I am doing something wrong in the container. I am a beginner in react-redux, I don't know what I am doing wrong. I've already read all the posts but nothing seems to works. my reducer:


const initialState={
  articles: [],
}; 

const rootReducer = (state = initialState, action) => {
  const { type, payload }=action;
  switch(type) {
    case SRETRIEVE_ARTICLE:{
      return {
        ...state,
        articles:payload,
      };
    }

    default: return state;
  }
}

export default rootReducer;

This is what I have right now in container:

import Articles from 'components/Articles';
import { fetchArticles } from '../../pages/index';

const mapStateToProps = (state) => ({
    articles:state.articles
  })

  const ConnectedArticles = connect(
    mapStateToProps,
    {fetchArticles}
  )(Articles)

export default ConnectedArticles;

pages.js

  axios.get('API').then((response) => {
    const { data } = response;

    dispatch({ type: RETRIEVE_ARTICLES, payload: data });
  });
};

const Index = () => {
 
  const articles= useSelector((state) => state.articles);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchArticles);
  }, []);

  return <>{articles && articles.map((article) => <Article key={article.id} name={article.name} />)}</>;
};
Index.getInitialProps = async () => ({
  authRequired: true,
  label: 'Dashboard',
});



export default Index;

Also I defined the action type: export const SET_UNOPENED_REWARD = 'SET_UNOPENED_REWARD'; and action const unopenedRewards = (payload) => ({ type: SET_UNOPENED_REWARD, payload });

5
  • How/where are you fetching the data? Commented Jul 20, 2021 at 8:02
  • Kinda unrelated, general feedback: the tutorial you are following on Redux is showing you very outdated techniques. I would recommend you to follow the official Redux tutorial, as that shows you a much more modern style of Redux that will make a lot of that code unneccessary (like, half of it) redux.js.org/tutorials/essentials/part-1-overview-concepts Commented Jul 20, 2021 at 8:04
  • I'm fetching data in page.js page export const fetchRewards = async (dispatch) => { axios.get('API').then((response) => { const { data } = response; dispatch({ type: SET_UNOPENED_REWARD, payload: data }); }); }; Commented Jul 20, 2021 at 8:18
  • Make sure you dispatch the return value of the action creator eg dispatch(fetchArticles()) instead of dispatch(fetchArticles) Commented Jul 20, 2021 at 9:48
  • I've tried to change the dispatch return value but nothing happens, I think I am missing something else Commented Jul 20, 2021 at 10:04

2 Answers 2

2

One very nice way to do data fetching with redux is to use redux toolkit's createAsyncThunk and createSlice functions.

// src/features/articles/articlesSlice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

export const fetchArticles = createAsyncThunk("articles/get", async () => {
  // Here you can use axios with your own api
  const response = await fetch("https://rickandmortyapi.com/api/character");
  const json = await response.json();
  return json.results;
});

export const slice = createSlice({
  name: "articles",
  initialState: {
    loading: false,
    data: []
  },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(fetchArticles.pending, (state) => {
      state.loading = true;
    });
    builder.addCase(fetchArticles.fulfilled, (state, action) => {
      state.data = action.payload;
      state.loading = false;
    });
    builder.addCase(fetchArticles.rejected, (state) => {
      state.loading = false;
    });
  }
});
export default slice.reducer;

// src/features/articles/Articles.js

import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchArticles } from "./articlesSlice";

export const Articles = () => {
  const articles = useSelector((state) => state.articles.data);
  const loading = useSelector((state) => state.articles.loading);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(fetchArticles());
  }, []);

  return (
    <>
      {loading && "...loading"}
      {articles.map((article) => <Article key={article.id} {...article} />)}
    </>
  );
};

Edit nice-leaf-z9wx7

Sign up to request clarification or add additional context in comments.

Comments

0

you should use async and await

let response = await axios.get('https://run.mocky.io/v3/5c045896-3d18-4c71-a4e5-5ed32fbbe2de')

if(response.status==200){
   dispatch({ type: RETRIEVE_ARTICLES, payload: data });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.