Redux thunk fetch 返回函数而不是值

问题描述 投票:0回答:2

大家好我是一个初学者,目前正在学习编程,我正在尝试制作一个从 reddit 获取帖子并将其显示在网站上的 webapp,我创建了一个异步 thunk 来从 reddit API 获取数据,当我登录时它到控制台显示数据,但每当我尝试调用 fetch 函数并将其保存到 const 而不是像通常那样返回对象时,它返回函数。

Picture of the array returned by 'fetchNewPosts()' in reddit.js & the fetch call  by 'getPosts() in postSlice.js'

reddit.js API 获取函数

export const API_URL = 'https://www.reddit.com';

export const fetchNewPosts = () => async () => {
    const response = await fetch(`${API_URL}/new.json`);
    const json = await response.json();
    console.log(json.data.children.map((post) => post.data))
    const posts = json.data.children.map((post) => post.data)
    return posts
}

Feed.jsx 'fetchNewPosts()' 在 Feed.jsx 中发送时呈现一个包含 25 个帖子的对象

import React from 'react';
import {Stats} from '../components/Stats';
import { Post } from '../components/Post/Post'
import { useDispatch, useSelector } from 'react-redux';
import './Feed.css'
import { useEffect } from 'react';
import { getPosts } from '../api/postsSlice';
import { fetchNewPosts } from '../api/reddit';


export const Feed = () => {
  const allInfo = useSelector(state => state.postsReducer);
  const { posts, isLoading, error } = allInfo;
  const dispatch = useDispatch();

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

...

postsSlice.js

    import { createSlice } from "@reduxjs/toolkit";
import { fetchNewPosts } from "./reddit";


export const postsSlice = createSlice({
    name: 'postsSlice',
    initialState: {
        posts: [],
        isLoading: false,
        error: false,
        errorMessage: '',
        searchTerm: '',
    },
    reducers: {
        startGetPosts (state) {
            state.isLoading = true;
        },
        getPostsSuccess (state, action) {
            state.isLoading = false;
            state.posts = action.payload;
        },
        getPostsFailed (state, action) {
            state.isLoading = false;
            state.error = true;
            state.errorMessage = action.payload;
        }
    }
})



export const getPosts = () => async (dispatch) => {
    try {
        dispatch(startGetPosts());
        const posts = await fetchNewPosts();
        console.log(posts)
        dispatch(getPostsSuccess());
    } catch (error) {
        dispatch(getPostsFailed(error.message))
    }
}


export const selectPosts = (state) => state.postsSlice.posts;

export const { 
    startGetPosts, 
    getPostsSuccess, 
    getPostsFailed 
} = postsSlice.actions;

export default postsSlice.reducer; 

感谢我能得到的任何反馈。

javascript reactjs redux fetch-api redux-thunk
2个回答
0
投票

您缺少的关键是 在 Redux 中更新状态的 唯一 方法是“调度”一个描述“发生了什么”并包含描述/数据的操作对象! 现在您的代码不是这样做。

fetchNewPosts
看起来像这样:

export const fetchNewPosts = () => async () => {
    const response = await fetch(`${API_URL}/new.json`);
    const json = await response.json();
    console.log(json.data.children.map((post) => post.data))
    const posts = json.data.children.map((post) => post.data)
    return posts
}

大部分没问题。

它有一个“thunk action creator”的形式,其中有一个可以做一些异步工作的内部函数。那很好。

前三行很好,一直到

const posts = data.children.map()
。你提出了请求,取回了数据,并提取了你需要的东西。

然而,

return posts
是错误的。 而不是返回值,您需要调度一个包含值的动作

幸运的是,thunk 函数在被调用时被赋予了 Redux

dispatch
函数。所以,你可以把它改成这样:

// Add dispatch as an arg to the inner function
export const fetchNewPosts = () => async (dispatch) => {
    const response = await fetch(`${API_URL}/new.json`);
    const json = await response.json();

    const posts = json.data.children.map((post) => post.data)
    // Dispatch an action containing the data
    // Assume that `somePostsReceivedAction` is defined elsewhere
    dispatch(somePostsReceivedAction(posts));
}

请注意,如果您使用我们的官方 Redux 工具包,这会变得更容易。它有一个

createAsyncThunk
API does 让您只需发出请求并返回数据,它就会为您调度操作:

const fetchNewPosts2 = createAsyncThunk(
  'posts/fetchNewPosts',
  async () => {
    const response = await fetch(`${API_URL}/new.json`);
    const json = await response.json();
    return son.data.children.map((post) => post.data)
  }
)

查看我们的 Redux 文档教程以更好地了解什么是 thunk、如何使用它们以及如何使用 Redux Toolkit:


0
投票

我有同样的问题,对原始问题提供的答案似乎没有阐明为什么

fetch()
返回的是函数而不是对象。

我的

createAsyncThunk()
长这样:

export const fetch = createAsyncThunk(
"feed/get",
async (feed) => {
    const data = await fetch(`https://www.reddit.com/r/meirl/comments/136g1rn/meirl.json`);
    console.log(typeof(data)); //Prints: "function"
    const res = await data.json();
    return res;
})

任何想法表示赞赏!

© www.soinside.com 2019 - 2024. All rights reserved.