简体   繁体   English

为 React 组件导出在 fetch() function 中的 then() 方法中创建的变量

[英]Export a variable created inside a then() method within a fetch() function for a React Component

I need to start from the very beginning to summarize my problem:我需要从头开始总结我的问题:

I'm creating a structure with a react framework to build a simple reactive page.我正在创建一个带有反应框架的结构来构建一个简单的反应页面。 I guess I can define it as a single page application:我想我可以将其定义为单页应用程序:

Here's the structure:这是结构:

在此处输入图像描述

Right now my article-content.js file has the following code:现在我的 article-content.js 文件有以下代码:

import $ from "jquery";
const rootURL = 'mytargetwebsite';

const config = {
    rootURL: rootURL,
    taskRoute: `${rootURL}/wp-json/wp/v2/posts`,
};


let articles = '';
let the_request = $.ajax({
    type: 'GET',
    url: config.taskRoute,
    async: false,
});

the_request.done(function(data){

    articles = data.map(data => (

    {
        name: data.title.rendered,
        title: data.link,
        excerpt: data.excerpt.rendered,
        content: data.content.rendered
    }

    ));

});
export default articles;

And it works fine but ideally, this is not how I want to run my app, because my goal is to use a promise or the fetch API to export the variable and reuse it in another file, which is the following:它工作正常,但理想情况下,这不是我想要运行我的应用程序的方式,因为我的目标是使用 promise 或 fetch API 来导出变量并在另一个文件中重用它,如下所示:

ArticlesList.js:文章列表.js:

import React from 'react';
import { Link } from 'react-router-dom';

const ArticlesList = ({ articles }) => (
    <>
    {articles.map((article, key) => (
        <Link className="article-list-item" key={key} to={`/article/${article.name}`}>
            <h3>{article.title}</h3>
            <h3>{article.name}</h3>
            {/*<div>{article.content}</div>*/}
            <div
            dangerouslySetInnerHTML={{
                __html: article.content
            }}></div>
        </Link>
    ))}
    </>
);

export default ArticlesList;

So, I tried to use the fetch API several times, but I'm not able to export it because, when I try to run the.map function on the ArticlesList.js page an error will be thrown.所以,我尝试使用 fetch API 几次,但我无法导出它,因为当我尝试运行.map function 时,会在 ArticlesList.js 页面上抛出错误。

Something like:就像是:

const ciao = async () => { 
    function fetchDemo() {
        return fetch(config.taskRoute).then(function(response) {
            return response.json();
        }).then(function(json) {
            let articles = json.map(data => (
            {
                name: data.title.rendered,
                title: data.link,
                content: data.content.rendered
            }
            ));
            return articles;

        });
    }
}
const articles = ciao();
console.log(articles);

will never work for some reason but, on the other hand, the idea will work, so the articles will log a promise that it is resolved and contains the data that I need to map or loop through that I need on the other page.由于某种原因永远不会起作用,但另一方面,这个想法会起作用,所以文章将记录一个 promise,它已解决并包含我需要的数据到 map 或循环通过我在另一页上需要的数据。

The approach with the promise is very similar and, like in the other case, will work: promise 的方法非常相似,并且与其他情况一样,将起作用:

const articles = new Promise((resolve,reject) => {
    fetch(config.taskRoute, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json', },
    })
    .then(response => response.json())
    .then(data => {
        resolve(data.map(data => ({
            name: data.title.rendered,
            title: data.link,
            content: data.content.rendered
        })));
    })
    .catch((error) => {
        reject(error)
    });
});

export default articles;

But still, I won't be able to export my variable because it will fail in the other file (ArticlesList.js).但是,我仍然无法导出我的变量,因为它将在另一个文件 (ArticlesList.js) 中失败。

I tried several other approaches but they all fail so far.我尝试了其他几种方法,但到目前为止它们都失败了。

Any hint?有什么提示吗?

UPDATE:更新:

There must be something that I can't know because in theory, my code works fine:一定有一些我不知道的东西,因为理论上我的代码可以正常工作:

ArticlesList.js文章列表.js

import React from 'react';
import { Link } from 'react-router-dom';
import articles from "../pages/article-content";

articles.then(articles => {
    console.log(articles);
    return;

});

If I console.log articles, it contains the value that I need to map but as soon as I try to map them:如果我 console.log 文章,它包含我需要 map 但一旦我尝试 map 他们的值:

console.log(articles);//works!
const ArticlesList = ({ articles }) => (
    <>
    {articles.map((article, key) => (
        <Link className="article-list-item" key={key} to={`/article/${article.name}`}>
            <h3>{article.title}</h3>
            <h3>{article.name}</h3>
            {/*<div>{article.content}</div>*/}
            <div
            dangerouslySetInnerHTML={{
                __html: article.content
            }}></div>
        </Link>
    ))}
    </>
);//doesn't work

I will get a:我会得到一个:

TypeError: articles.map is not a function

Rather than trying to export articles (which is not possible for many reasons) why not simply export a promise which resolves with articles?与其尝试导出articles (由于许多原因这是不可能的),为什么不简单地导出用文章解析的 promise 呢?

const rootURL = 'mywebsite';

const config = {
    rootURL: rootURL,
    taskRoute: `${rootURL}/wp-json/wp/v2/posts`,
}

const articles = new Promise((resolve,reject) => {
    fetch(config.taskRoute, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json', },
    })
    .then(response => response.json())
    .then(data => {
        resolve(data.map(data => ({
            name: data.title.rendered,
            title: data.link,
            content: data.content.rendered
        })));
    })
    .catch((error) => {
        reject(error)
    });
});

export default articles;

In the importing file在导入文件中

import articles from "./articles";

articles.then(articlesArray => {
    // Here articlesArray is an array and it must be used in this function
});

// Here aritclesArray is not defined

Note this approach works only if you need to load articles at boot time, if you need to load again articles later in your app, it's better to export a function which return a Promise rather than exporting the Promise itself.请注意,此方法仅在您需要在启动时加载文章时才有效,如果您需要稍后在应用程序中再次加载文章,最好导出返回 Promise 的 function 而不是导出 ZA5A3F0F2807A44898AZ2AAC2本身。

Instead of exporting the articles you should export a function that fetches articles and then take care of all the async-await's or promises to resolve the function in the respective component that you use the function in而不是导出文章,您应该导出获取文章的 function,然后处理所有异步等待或承诺在您使用 ZC1C4245268E68384F1C 的相应组件中解析 function

const rootURL = 'mywebsite.xyz/';

const config = {
    rootURL: rootURL,
    taskRoute: `${rootURL}/wp-json/wp/v2/posts`,
};

const getPeopleInSpace = () => 
    return fetch(config.taskRoute) 
       .then(res => res.json());

const getArticles = () => 
    getPeopleInSpace()
    .then(json => {
        const article = json.map(data => {
            return {
            name: data.title.rendered,
                title: data.link,
                content: data.content.rendered
            }
        });
        return article;
    })

export default getArticles ;

Now you can use the above function in any component like现在您可以在任何组件中使用上述 function

import getArticles from 'path/to/getArticles';

class App extends React.Component {
   ...
   componentDidMount() {
       getArticles().then(articles => {
          console.log(articles);
          // set articles in state and use them
       }) 
   }
}

One reason why you shouldn't be exporting articles fetched from an API is because everytime you import the file, a new request goes, but you are never guranteed when the request is complete and your items are available to be used.您不应该导出从 API 获取的文章的一个原因是,每次您导入文件时,都会发出一个新请求,但是当请求完成并且您的项目可供使用时,您永远无法得到保证。 By exporting the function you can handle the success and error scenarios通过导出 function 您可以处理成功和错误场景

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

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