使用 React 和 Redux 应用程序从 JSON 文件中获取数据
大多数时候,当我们获取数据时,我们是从作为服务器的外部端点 (API) 进行的。获取该数据后,我们对其执行 CRUD(创建、读取、更新、删除)操作。 本文将演示如何在 React & Redux 应用程序中正确地从 JSON 文件中获取数据并在前端使用它,同时解释 React-Redux 的工作流程。 我们将创建一个徽章来奖励获得超过 5 票的用户。我们将在本地模拟 JSON 数据,并为每个拥有超
大多数时候,当我们获取数据时,我们是从作为服务器的外部端点 (API) 进行的。获取该数据后,我们对其执行 CRUD(创建、读取、更新、删除)操作。
本文将演示如何在 React & Redux 应用程序中正确地从 JSON 文件中获取数据并在前端使用它,同时解释 React-Redux 的工作流程。
我们将创建一个徽章来奖励获得超过 5 票的用户。我们将在本地模拟 JSON 数据,并为每个拥有超过five-votes
的用户提供一个徽章,使用 react 和 redux 来消费数据。
在继续之前,我假设您具有React、React-Redux和JSON的基本知识。
设置本地 JSON 文件
在一个空白的 Create React App 项目中,在公共目录中创建一个名为data.json
的本地 JSON 文件。
从 React 组件进行的 Fetch API 调用始终在此公共目录中查找文件或任何其他相关资产。Create-React-App
在编译期间不会自动将您的资产放入此目录中,因此您必须手动执行此操作。
接下来,将一些虚拟 JSON 数据放入此文件中。出于演示目的,以下示例中使用的 JSON 数据是从 JSON Generator 生成的。如果您使用自己的 JSON,请确保其格式正确。
[
{
"id": 1,
"name": "Daniel",
"email": "[email protected]",
"post": "I love football",
"votes": 5
}
]
**设置 React-Redux **
我们需要安装一些依赖项,我们将在整个项目中使用它们。
要安装它,请在终端中打开您的项目目录并编写以下代码:
npm i -s react-redux redux axios redux-thunk
or
yarn add react-redux redux axios
此外,我们将安装fontaweasome
,我们将在其中导入图标作为徽章。
npm i --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/react-fontawesome
或者
yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/react-fontawesome
在 src/ 目录中,让我们制作 6 个文件
-
src/
-
常量.js
-
action.js
-
reducer.js
-
store.js
-
fontAwesome.js
src/constants.js
在 constant.js 中,我们需要添加一个获取用户的状态:
const USER = {
LOAD: "REQUEST_USERS_DATA",
LOAD_SUCCESS: "RECEIVE_USERS_DATA",
};
export default USER;
src/reducer.js
我们将在 reducer 中导入常量。 reducer 是一个纯函数,它采取一个动作和应用程序的初始状态并返回新状态。
action 描述了发生了什么,reducer 的工作是根据该 action 返回到新状态。
import USER from "./constants";
const initalState = {
usersData: [],
isLoading: false,
isError: false,
};
const reducer = (state = initalState, action) => {
switch (action.type) {
case USER.LOAD:
return {
...state,
isLoading: true,
isError: false,
};
case USER.LOAD_SUCCESS:
return {
...state,
usersData: action.usersData,
isLoading: false,
};
default:
return state;
}
};
export default reducer;
src/action.js
此操作文件携带来自您的应用程序的信息负载以进行存储。
Redux 依赖于由 reducer 分发和监听的 action,reducers 会相应地更新状态。
import axios from "axios";
import USER from "./constants";
export const requestUsers = (data) => async (dispatch) => {
dispatch({
type: USER.LOAD,
});
try {
const json = await axios.get("data.json");
console.log(json);
dispatch({
type: USER.LOAD_SUCCESS,
usersData: json.data,
isError: false,
});
} catch (e) {
dispatch({
type: USER.LOAD_SUCCESS,
usersData: [],
isError: true,
});
}
};
src/index.js
在索引文件中,我们将导入fontawesome
,以便任何组件都可以从它继承。
我们还需要提供者和商店。 Provider 组件使 Redux 存储可供任何需要访问 Redux 存储的嵌套组件使用。
Redux 存储是全局状态,用于存储您想要跨多个组件使用的数据,而无需在组件树的每个级别上钻取 props。 Redux 存储对存储的数据量没有限制,因此您几乎可以使用它来存储几乎任何东西,包括庞大的 JSON 数据。
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { store } from "./store";
import { Provider } from "react-redux";
import "./fontAwesome";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
src/fontAwesome.js
import { library } from "@fortawesome/fontawesome-svg-core";
import {
faGithubAlt,
faGoogle,
faFacebook,
faTwitter,
faJediOrder,
} from "@fortawesome/free-brands-svg-icons";
library.add(faGithubAlt, faGoogle, faFacebook, faTwitter, faJediOrder);
src/store.js
一个 store 保存着应用程序的整个状态树。
改变内部状态的唯一方法是对它发送一个动作。然后 store 将从 reducer 接收到的新状态传递给组件。
import thunkMiddleware from "redux-thunk";
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
export const store = createStore(reducer, applyMiddleware(thunkMiddleware));
src/data.js
[
{
"id": 1,
"name": "Daniel",
"email": "[email protected]",
"post": "I love football",
"votes": 5
}
]
src/App.js
我们从 react-redux 导入以下钩子:useSelector
和useDispatch
。
useSelector
是一个函数,它将当前状态作为参数并返回您想要的任何数据,它允许您将返回值存储在函数组件范围内的变量中,而不是将它们作为道具传递下来。
useDispatch
等价于mapDispatchToProps
。我们将调用useDispatch
并将其存储到变量 dispatch。这个钩子从 Redux 存储中返回对 dispatch 函数的引用。
您可以根据需要使用它来调度操作。我们通过调用 dispatch 并传入动作创建者的返回值来调度它。
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { requestUsers } from "./action";
import data from "./data.json";
import "./App.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const App = () => {
const { usersData, isLoading } = useSelector((state) => state);
const dispatch = useDispatch();
useEffect(() => {
dispatch(requestUsers(data));
}, []);
return (
<>
{isLoading && <div className="loading">Data loading...</div>}
{usersData.map((user) => {
return (
<div key={user.id} className="container">
<div className="content">
<h1>{user.name}</h1>
<span>{user.email}</span>
<h3>{user.post}</h3>
Votes: {user.votes}
{user.votes >= 5 ? (
<div>
<FontAwesomeIcon icon={["fab", "jedi-order"]} size="3x" />
</div>
) : (
<p>Get up to five votes to have a badge</p>
)}
</div>
</div>
);
})}
</>
);
};
export default App;
React-Redux 工作流程总结
![](data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27543%27%20height=%27159%27/%3e)
<img altu003d"redux 数据流程图" srcsetu003d"/_next/image?urlu003dhttps%3A%2F%2Fcdn.hackernoon.com%2Fimages%2FmyobtPSoKbQcY9jJlWQFuYiQqC42-4y9ac35jy.jpeg&wu003d640&qu003d75 1x, /_next/ image?urlu003dhttps%3A%2F%2Fcdn.hackernoon.com%2Fimages%2FmyobtPSoKbQcY9jJlWQFuYiQqC42-4y9ac35jy.jpeg&wu003d1200&qu003d75 2x" srcu003d"/_next/image?urlu003dhttps%3A%2F%2Fcdn.hackernoon. com%2Fimages%2FmyobtPSoKbQcY9jJlWQFuYiQqC42-4y9ac35jy.jpeg&wu003d1200&qu003d75" 解码u003d"async" data-nimgu003d"intrinsic" styleu003d"position:absolute;top:0;left:0;bottom:0;right:0;box -sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100 %;max-height:100%;object-fit:contain" classu003d"image" loadingu003d"lazy">
redux 数据流程图
Redux 是 javascript 的可预测状态容器。
所以在一个 redux 数据流中,我们有一个 javascript 应用程序,它是应用程序的状态在 redux 存储中维护,但是,应用程序不能直接更新状态,它使用一个动作或调度一个动作来维护状态。一旦动作被调度,reducer 就会处理动作并更新当前存储。
Redux 在单页应用程序 (SPA) 中非常有用,因为它产生了单一的事实来源。 Redux 有一个 store,store 是一个包含整个应用程序状态的对象。不同的状态片段存储在对象树中。
要阅读有关 React-Redux 的更多信息,您可以阅读此文档。
编码愉快!
更多推荐
所有评论(0)