【问题标题】:React/Redux - Pass variable to actionReact/Redux - 将变量传递给动作
【发布时间】:2023-03-13 07:10:02
【问题描述】:

我是 Redux 的新手,正在使用 Spotify API 进行项目。我正在发送 API 调用并检索有关当前播放歌曲的数据。

我有一个单独的 Redux 操作,它试图从当前播放的艺术家那里获取其他专辑。在我的 App.js 中,我可以通过 const id = this.props.currentlyPlaying.id 访问艺术家的 ID

我想将此变量从 App.js 传递给我的相册操作。该操作包含 API 调用,如下所示:

import SpotifyWebApi from 'spotify-web-api-js';
import {id} from '../App.js';
const spotifyApi = new SpotifyWebApi();

export function fetchAlbums() {
  return function(dispatch) {
    dispatch({ type: "FETCH_ALBUMS_BY_ARTIST"});

    //'43ZHCT0cAZBISjO8DG9PnE'
    spotifyApi.getArtistAlbums(id)
      .then((response) => {
        dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_FULFILLED", payload: response})
      })
      .catch((err) => {
        dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_REJECTED", payload: err})
      });

  }
}

我尝试导入 id 变量,但出现错误。将变量从组件传递到 Redux 操作的正确方法是什么?我也试过通过this.props直接在action中访问id,也不管用。

【问题讨论】:

    标签: reactjs variables redux react-redux action


    【解决方案1】:

    不要尝试导入 id,在调用fetchAlbums 操作时将其作为参数传递。

    类似:

    动作:

    export const fetchAlbums = (id) => async dispatch => {
      dispatch({ type: "FETCH_ALBUMS_BY_ARTIST"});
    
      //'43ZHCT0cAZBISjO8DG9PnE'
      spotifyApi.getArtistAlbums(id)
        .then((response) => {
          dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_FULFILLED", payload: response})
        })
        .catch((err) => {
          dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_REJECTED", payload: err})
        });
    }
    

    使用行动:

    这将绑定一个函数来调用fetchAlbums 函数,允许您传递参数而不是click 事件。

    <button onClick={() => fetchAlbums(id)}>Fetch Album</button>
    

    【讨论】:

      【解决方案2】:

      您需要做的是,当您从组件调用操作时,将 th id 传递给操作函数。像这样: 我还会推荐你使用 redux-thunk 中间件来处理异步操作。

      export function fetchAlbums(id) {
        return function(dispatch,id) {
          dispatch({ type: "FETCH_ALBUMS_BY_ARTIST"});
      
          //'43ZHCT0cAZBISjO8DG9PnE'
          spotifyApi.getArtistAlbums(id)
            .then((response) => {
              dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_FULFILLED", payload: response})
            })
            .catch((err) => {
              dispatch({ type: "FETCH_ALBUMS_BY_ARTIST_REJECTED", payload: err})
            });
      
        }
      }
      

      【讨论】:

        【解决方案3】:

        我的配置:

            "react": "^17.0.2",
            "react-dom": "^17.0.2",
            "react-redux": "^7.2.6",
        

        我们可以像这样将值传递给调度函数,

        切片文件

        import { createSlice } from '@reduxjs/toolkit'
        
        export const rootSlice = createSlice({
            name: 'root',
            initialState: {
                posts: [
                    { id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" },
                    { id: 2, title: "qui est esse", body: "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" },
                    { id: 3, title: "ea molestias quasi exercitationem repellat qui ipsa sit aut", body: "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" },
                ],
            },
            reducers: {
                deletePost: (state, action) => {
                    console.log("state: " + state.posts)
                    console.log("action: " + action.payload.id)
                    console.log("action: " + action.payload.extra_val)
                    // to do
                    let newPost = state.posts.filter(post => {
                        return action.payload.id !== post.id
                    })
                    return {
                        ...state,
                        posts: newPost
                    }
                },
            },
        })
        
        // Action creators are generated for each case reducer function
        export const { deletePost } = rootSlice.actions
        
        export default rootSlice.reducer
        

        发布文件

        import React from 'react';
        import { useParams, useNavigate } from 'react-router-dom';
        import { useSelector, useDispatch } from 'react-redux'
        import { deletePost } from '../reducers/rootSlice'
        
        const Post = () => {
            let navigate = useNavigate();
            let { post_id } = useParams();
            const posts = useSelector((state) => state.root.posts);
            var singPost = (id) => posts.find(obj => obj.id === parseInt(id))
            const dispatch = useDispatch()
        
            const handleClick = (id) => {
                dispatch(deletePost({ id, extra_val: 'ok-1' }));
                navigate("/");
            }
        
            const post = (id) => {
                var sp = singPost(id);
                return sp ? (
                    <div className="post">
                        <h4 className="center">{sp.title}</h4>
                        <p>{sp.body}</p>
                        <button onClick={() => handleClick(sp.id)}>deletePost</button>
                    </div>
                ) : (
                    <div className="center">Loading posts...</div>
                );
            }
            return (
                <div className="container">
                    {post(post_id)}
                </div>
            );
        }
        
        export default Post;
        

        参考:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-09
          • 1970-01-01
          • 2019-02-18
          • 1970-01-01
          • 2020-05-05
          相关资源
          最近更新 更多