简体   繁体   English

如何从 React 组件中重构异步函数

[英]How to Refactor an Async Function out of a React Component

I have a straightforward react component that looks so in AllWords.js :我有一个在AllWords.js中看起来如此简单的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;

I would like to refactor the fetchData() method out of the component into another file (basically a separate .js file that holds the fetch call).我想将组件中的fetchData()方法重构为另一个文件(基本上是一个单独的.js文件,用于保存 fetch 调用)。

What I would like is to have created a file titled FetchAllWords.js under src/actions/ & then import it.我想要的是在src/actions/下创建一个名为FetchAllWords.js的文件,然后导入它。 & use that. &使用那个。

I have several questions :我有几个问题:

  1. do I need to set the state in the FetchAllWords.js and then useSelector to extract the state in AllWords.js ?我是否需要在FetchAllWords.js设置state ,然后使用useSelectorAllWords.js提取状态?
  2. in FetchAllWords.js do I need to usedispatch to dispatch a method call setting the state ?FetchAllWords.js ,我是否需要使用usedispatch来调度设置state的方法调用? I would like to just setState in FetchAllWords.js and then extract it in AllWords.js .我想刚才setStateFetchAllWords.js然后提取它AllWords.js This is what I have so far:这是我到目前为止:
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;

I am unsure how to import this and use it in AllWords.js .我不确定如何导入它并在AllWords.js使用它。 I am using the following statement : import wordList from '../../actions/FetchAllWords';我正在使用以下语句: import wordList from '../../actions/FetchAllWords';

Then I am trying to use wordList as a handle to the file '../../actions/FetchAllWords.js' & attempting to access the async function FetchAllWords so wordList.FetchAllWords() ;然后我尝试使用wordList作为文件'../../actions/FetchAllWords.js'的句柄并尝试访问async function FetchAllWords所以wordList.FetchAllWords() ;

Firstly , the editor (VSCode) won't let me see the function despite the import call.首先,尽管调用了导入,编辑器 (VSCode) 也不会让我看到该函数。

Secondly I am getting an error (something like) : TypeError: _actions_FetchAllWords_js__WEBPACK_IMPORTED_MODULE_3__.default.FetchAllWords is not a function其次,我收到一个错误(类似): TypeError: _actions_FetchAllWords_js__WEBPACK_IMPORTED_MODULE_3__.default.FetchAllWords is not a function

Any insight or help would be appreciated since rather uneasy with JS & React.任何见解或帮助将不胜感激,因为对 JS 和 React 相当不安。 The github repo is : https://github.com/mrarthurwhite/hooks-p5-react-redux github 仓库是: https : //github.com/mrarthurwhite/hooks-p5-react-redux

EDIT : As per David's suggestions :编辑:根据大卫的建议:

So AllWords.js React component is :所以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;

And Fetch.js is :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;

No, don't worry about state in the external file.不,不要担心外部文件中的状态。 Just focus on the one thing it should do, perform the AJAX operation.只需专注于它应该做的一件事,即执行 AJAX 操作。 At its simplest it's just a function, something like:简而言之,它只是一个函数,例如:

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;

You can even make it a class which contains this function, if you plan on adding other service operations as well.如果您还计划添加其他服务操作,您甚至可以将其设置为包含此功能的类。 (Fetch specific word? Find word? etc.) The point is that this does just one thing, provide data. (获取特定单词?查找单词?等) 重点是这仅做一件事,即提供数据。 Let the React components handle React state.让 React 组件处理 React 状态。

Within the component you'd just use that to get your data.在组件中,您只需使用它来获取数据。 Something like:就像是:

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;

Overall it's a matter of separating concerns.总的来说,这是一个分离关注点的问题。 The service performs the AJAX operation and returns the meaningful data, internally concerned with things like JSON deserialization and whatnot.该服务执行 AJAX 操作并返回有意义的数据,内部关注诸如 JSON 反序列化之类的事情。 The React component maintains the state and renders the output, internally concerned with updating state after useEffect runs and whatnot. React 组件维护状态并呈现输出,内部关注useEffect运行后更新状态等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM