javascript - 如何从 React 组件中重构异步函数
问题描述
我有一个简单的反应组件,看起来如此AllWords.js
:
import React, { useEffect, useState } from 'react';
import consts from '../../constants/Constants.js';
function AllWords() {
const [words, setWords] = useState([]);
async function fetchData(){
const response= await fetch(consts.FETCH_URL);
const data = await (response.json());
setWords(data);
};
// API: useEffect( () => { . . . return cleanup; },[var_n_whose_change_triggers_useEffect . . .] );
useEffect(() => {fetchData()}, [] );
return (
<>
{
words.map(w=> <div>{w.word}</div>)
}
</>
);
}
export default AllWords;
我想将fetchData()
组件中的方法重构到另一个文件中(基本上是一个.js
包含 fetch 调用的单独文件)。
我想要的是创建一个标题为FetchAllWords.js
&src/actions/
然后导入它的文件。并使用它。
我有几个问题:
- 我需要设置
state
inFetchAllWords.js
然后useSelector
提取状态AllWords.js
吗? - 我
FetchAllWords.js
是否需要usedispatch
调度方法调用设置state
?我想将其setState
放入FetchAllWords.js
然后将其提取到AllWords.js
. 这是我到目前为止所拥有的:
import consts from '../constants/Constants.js';
import { useState } from 'react';
async function FetchAllWords(){
const [words, setWords] = useState([]);
const response= await fetch(consts.FETCH_URL);
const data = await (response.json());
setWords(data);
}
export default FetchAllWords;
我不确定如何导入它并在AllWords.js
. 我正在使用以下语句:
import wordList from '../../actions/FetchAllWords';
然后我尝试将其wordList
用作文件的句柄'../../actions/FetchAllWords.js'
并尝试访问async function
FetchAllWords
so wordList.FetchAllWords()
;
首先,尽管导入调用,编辑器(VSCode)不会让我看到该功能。
其次,我收到一个错误(类似):
TypeError: _actions_FetchAllWords_js__WEBPACK_IMPORTED_MODULE_3__.default.FetchAllWords is not a function
任何见解或帮助将不胜感激,因为 JS 和 React 相当不安。github 仓库是:https ://github.com/mrarthurwhite/hooks-p5-react-redux
编辑:根据大卫的建议:
所以AllWords.js
React 组件是:
import React, { useEffect, useState } from 'react';
import wordList from '../../services/Fetch.js';
function AllWords() {
const [words, setWords] = useState([]);
function fetchData(){
wordList.fetchAllWords().then(
data => setWords(data)
);
};
// API: useEffect( () => { . . . return cleanup; },[var_n_whose_change_triggers_useEffect . . .] );
useEffect(() => {fetchData()}, [] );
return (
<>
{
words.map(w=> <div>{w.word}</div>)
}
</>
);
}
export default AllWords;
并且Fetch.js
是:
import consts from '../constants/Constants.js';
class Fetch {
async fetchAllWords(){
const response= await fetch(consts.FETCH_URL);
const data = await (response.json());
return data;
}
}
export default Fetch;
解决方案
不,不用担心外部文件中的状态。只关注它应该做的一件事,执行 AJAX 操作。在最简单的情况下,它只是一个函数,例如:
import consts from '../../constants/Constants.js';
const fetchAllWords = async () => {
const response = await fetch(consts.FETCH_URL);
const data = await (response.json());
return data;
}
export default fetchAllWords;
如果您还计划添加其他服务操作,您甚至可以将其设为包含此功能的类。(获取特定单词?查找单词?等等。)关键是它只做一件事,提供数据。让 React 组件处理 React 状态。
在组件中,您只需使用它来获取数据。就像是:
import React, { useEffect, useState } from 'react';
import fetchAllWords from '../../services/FetchAllWords.js';
function AllWords() {
const [words, setWords] = useState([]);
useEffect(() => {
fetchAllWords().then(w => setWords(w));
}, []);
return (
<>
{
words.map(w=> <div>{w.word}</div>)
}
</>
);
}
export default AllWords;
总的来说,这是一个分离关注点的问题。该服务执行 AJAX 操作并返回有意义的数据,内部涉及诸如 JSON 反序列化之类的事情。React 组件维护状态并渲染输出,内部关注useEffect
运行后更新状态等等。
推荐阅读
- regex - 使用 RegEx 提取具有不同标点符号的长字符串的不同部分
- python - 如何每次都将列表的不同元素设置为增量,以便我可以编辑另一个列表元素?
- xcode - Xcode build 在派生数据文件夹中找不到文件
- mysql - MySQL 是否支持 UPDATE SET FROM 语法?
- git - Azure DevOps Releases 跨分支构建管道
- amazon-web-services - AWS 自动扩展组会终止仍在运行任务的 Druid 进程吗?
- java - 显示一个值与另一个值的距离的算法
- javascript - 如何隐藏预加载器屏幕上的滚动条?
- flutter - 如何在飞镖中操作字符串?
- elasticsearch - Elasticsearch 分片请求缓存中的 size=0 是什么意思?