React/Redux - 将变量传递给操作
React/Redux - Pass variable to action
我是 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 在操作中直接访问 id,这也不起作用。
当您从组件调用操作时,您需要做的是将 id 传递给操作 function.Like:
我也会推荐你使用 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})
});
}
}
不要尝试导入 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>
我的配置:
"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
Post 文件
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;
参考:
我是 Redux 的新手,正在使用 Spotify API 开发一个项目。我正在发送 API 个电话并检索有关当前播放歌曲的数据。
我有一个单独的 Redux 操作试图从当前正在播放的艺术家那里获取其他专辑。在我的 App.js 中,我可以通过 const id = this.props.currentlyPlaying.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 在操作中直接访问 id,这也不起作用。
当您从组件调用操作时,您需要做的是将 id 传递给操作 function.Like: 我也会推荐你使用 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})
});
}
}
不要尝试导入 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>
我的配置:
"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
Post 文件
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;
参考: