在 React-Redux 应用程序中显示来自 Reddit API 的数据涉及以下几个核心概念:
// store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;
// actions.js
export const FETCH_POSTS_REQUEST = 'FETCH_POSTS_REQUEST';
export const FETCH_POSTS_SUCCESS = 'FETCH_POSTS_SUCCESS';
export const FETCH_POSTS_FAILURE = 'FETCH_POSTS_FAILURE';
export const fetchPostsRequest = () => ({
type: FETCH_POSTS_REQUEST
});
export const fetchPostsSuccess = (posts) => ({
type: FETCH_POSTS_SUCCESS,
payload: posts
});
export const fetchPostsFailure = (error) => ({
type: FETCH_POSTS_FAILURE,
payload: error
});
export const fetchPosts = (subreddit = 'reactjs') => {
return async (dispatch) => {
dispatch(fetchPostsRequest());
try {
const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
const data = await response.json();
const posts = data.data.children.map(child => child.data);
dispatch(fetchPostsSuccess(posts));
} catch (error) {
dispatch(fetchPostsFailure(error.message));
}
};
};
// reducers.js
import {
FETCH_POSTS_REQUEST,
FETCH_POSTS_SUCCESS,
FETCH_POSTS_FAILURE
} from './actions';
const initialState = {
loading: false,
posts: [],
error: ''
};
const postsReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_POSTS_REQUEST:
return {
...state,
loading: true
};
case FETCH_POSTS_SUCCESS:
return {
loading: false,
posts: action.payload,
error: ''
};
case FETCH_POSTS_FAILURE:
return {
loading: false,
posts: [],
error: action.payload
};
default:
return state;
}
};
export default postsReducer;
// PostsList.js
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { fetchPosts } from './actions';
const PostsList = ({ posts, loading, error, fetchPosts }) => {
useEffect(() => {
fetchPosts();
}, [fetchPosts]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h2>Reddit Posts</h2>
<ul>
{posts.map(post => (
<li key={post.id}>
<a href={`https://reddit.com${post.permalink}`} target="_blank" rel="noopener noreferrer">
{post.title}
</a>
<span> ({post.num_comments} comments)</span>
</li>
))}
</ul>
</div>
);
};
const mapStateToProps = (state) => ({
posts: state.posts,
loading: state.loading,
error: state.error
});
export default connect(mapStateToProps, { fetchPosts })(PostsList);
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import PostsList from './PostsList';
function App() {
return (
<Provider store={store}>
<div className="App">
<PostsList />
</div>
</Provider>
);
}
export default App;
问题:直接从浏览器调用 Reddit API 可能会遇到 CORS 限制
解决方案:
问题:Reddit API 返回的数据结构嵌套较深
解决方案:
问题:频繁调用 API 导致性能下降
解决方案:
问题:需要实现无限滚动或分页
解决方案:
// 扩展 action 以支持分页
export const fetchPosts = (subreddit = 'reactjs', after = null) => {
return async (dispatch) => {
dispatch(fetchPostsRequest());
try {
let url = `https://www.reddit.com/r/${subreddit}.json`;
if (after) {
url += `?after=${after}`;
}
const response = await fetch(url);
const data = await response.json();
const posts = data.data.children.map(child => child.data);
dispatch(fetchPostsSuccess({
posts,
after: data.data.after // 保存下一页的标记
}));
} catch (error) {
dispatch(fetchPostsFailure(error.message));
}
};
};
通过以上实现,你可以构建一个完整的 React-Redux 应用程序来获取并显示 Reddit API 的数据。
没有搜到相关的沙龙