react数据从本地读取_如何将从Google表格读取的React应用程序部署到Netlify

react数据从本地读取

In this tutorial, we’re going to cover how to connect to a spreadsheet hosted on Google, display that information inside a React application, and deploy it to Netlify.

在本教程中,我们将介绍如何连接到Google托管的电子表格,如何在React应用程序中显示该信息并将其部署到Netlify。

Skip to “The Setup” if you don’t care where the data will be coming from or why I chose to build this. I won’t be mad, I promise.

如果您不在乎数据将来自何处或为什么选择构建它,则跳至“设置”。 我保证,我不会生气。

Right now the final result looks like this, but I’ll be adding more features to it shortly.

现在,最终结果看起来像这样,但是我很快会为其添加更多功能。

为什么 (The Why)

I love cars ? ?️. If you’re even slightly interested in cars, you’ve probably at some point stumbled upon Doug Demuro’s Youtube channel. He reviews a wide range of cars anywhere from a $3 Million Ferrari Enzo to a 3 wheeled BMW Isetta. Doug’s format is a little bit different than most user reviews. His roughly 20 minute videos have three main points:

我爱汽车吗? ️ 如果您甚至对汽车不太感兴趣,那么您可能会偶然发现Do ug Demuro的Youtube频道。 他评论了各种各样的汽车,包括价值300 万美元的法拉利Enzo t oa 3 轮式BMW Isetta。 Doug的格式与大多数用户评论略有不同。 他大约20分钟的视频有三个要点:

  • Interesting quirks and features: about 70% of the video is him taking about the car’s exterior and interior quirks. These can range from a paragraph in the owner’s manual to an interesting shape of the break lights.

    有趣的怪癖和功能:大约70%的视频是他关于汽车外观和内部怪癖的。 这些范围可以从使用手册中的段落到有趣的断灯形状。
  • Driving: about 20% of the video is Doug taking the car out on the road and making funny faces when he accelerates. He also talks about the interior noise, handling, speed, and so on.

    驾驶:大约有20%的视频是道格将汽车驶出公路,并在他加速时做鬼脸。 他还谈到了室内噪音,处理,速度等。
  • The DougScore: Doug created a spreadsheet with all the cars he’s ever reviewed (since creating the scoring system) and ranked all of them using his own system. It’s broken down into two categories:

    DougScore:Doug创建了一个电子表格,其中包含他曾经审查过的所有汽车(自创建计分系统以来),并使用自己的系统对所有汽车进行排名。 它分为两类:

    * Weekend Score: Essentially how much fun the car is.

    *周末分数:从本质上讲,这辆车有多有趣。

    * Daily Score: Essentially how practical the car is.

    *每日得分:从本质上讲,汽车的实用性。

That’s why, in my opinion, he can get over 1.5M views on a 25 minute video of a minivan ??‍. Since the videos are so quirky, and Doug himself is pretty quirky too, his following has come up with some creative comments. My favourite are the “Doug is the type of guy to…” remarks, like those above.

我认为,这就是为什么他可以在25分钟的微型货车视频中获得超过150万的观看次数。 由于视频是如此古怪,而且道格本人也很古怪,因此他的追随者提出了一些富有创意的评论。 我最喜欢的是“道格是那种……”。

And now, to all of you who have stuck around after that intro that has nothing to do with building an app, Google Sheets API, or React, here’s what I am on about.

现在,对于所有在介绍之后一直停留在与构建应用程序,Google Sheets API或React无关的人来说,这就是我要做的。

设置 (The Setup)

Doug keeps his spreadsheet on Google Sheets, and anyone with a link can access it. To me, it was hard to navigate. So I decided to see if there was a way to extend it and add some additional functionality.

道格将电子表格保存在Google表格中,任何有链接的人都可以访问它。 对我来说,这很难导航。 因此,我决定看看是否有扩展它并添加一些其他功能的方法。

React创建应用 (React Create App)

Facebook’s React boilerplate will get us started fairly quickly without the need to configure any backends. In your Terminal of choice (Hyper for me), go ahead and put in:

Facebook的React样板将使我们相当快速地开始,而无需配置任何后端。 在您选择的终端机(对我来说, 超级 )中,继续输入:

npx create-react-app doug-score
cd doug-score
yarn start

(Or npm start, whatever floats your boat but I'll be using yarn.)

(或者npm start ,无论您的船如何漂浮,但我将使用毛线。)

Open up the folder in your editor of choice (VS Code for me) and head over to App.js. We’re going to create a separate component called CarList , putting it inside a components folder and adding it to App .

在您选择的编辑器(对我而言是VS Code)中打开文件夹,然后转到App.js 我们将创建一个单独的名为CarList组件,将其放在components文件夹中,并将其添加到App

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import CarList from "./components/CarList";
class App extends Component {render() {return (<div className="App"><header className="App-header"><img src={logo} className="App-logo" alt="logo" /><h1 className="App-title">Welcome to React</h1></header><CarList /></div>);}
}
export default App;

For now, this is what CarList component will look like:

现在,这是CarList组件的外观:

import React, { Component } from 'react';
class CarList extends Component {render() {return (<div>This will be the car list</div>);}
}

Google Sheets API (Google Sheets API)

Let’s go ahead and create a new project on Google. I’ve called it doug-score. Once it’s been created, in the APIs box, click “Go to APIs overview.” Once you click “Enable APIs and Services” you’ll be presented with the API Library. We’ll go ahead and search for “Google Sheets API.” Once you click into it, click “Enable,” and after it’s processed you should see this page.

让我们继续, 在Google上创建一个新项目 。 我称它为doug-score 。 创建完成后,在“ API”框中,单击“转到API概述”。 单击“启用API和服务”后,您将看到API库。 我们将继续搜索“ Google Sheets API”。 单击后,单击“启用”,处理完成后,您应该会看到此页面。

In the sidebar, head over to “Credentials,” click the “Create credentials” button, and select “API Key.” Click the “Restrict Key” and set a name for it (I set it to “DougScore”). Under “Application Restrictions,” we’re going to set it to “HTTP referrers” and add http://localhost:3000 for now. Under “API Restrictions” select the “Google Sheets API” and save. We should be good to go on this end.

在边栏中,转到“凭据”,单击“创建凭据”按钮,然后选择“ API密钥”。 单击“限制键”并为其设置一个名称(我将其设置为“ DougScore”)。 在“应用程序限制”下,我们将其设置为“ HTTP Referrers”,并立即添加http://localhost:3000 。 在“ API限制”下,选择“ Google Sheets API”并保存。 我们应该为此而努力。

连接 (The Connection)

Now that we have an API key, head back over to the application code and create a new file called config.js . Input your API key and the spreadsheet ID into it.

现在我们有了一个API密钥,回到应用程序代码并创建一个名为config.js的新文件。 在其中输入您的API密钥和电子表格ID。

export default {apiKey: "YOUR_API_KEY",discoveryDocs: ["https://sheets.googleapis.com/$discovery/rest?version=v4"],spreadsheetId: "1KTArYwDWrn52fnc7B12KvjRb6nmcEaU6gXYehWfsZSo"
};

Now, we’ll need the Google API library, so we’ll use our index.html file inside the public library after our <div id="root"></div>

现在,我们需要Google API库,因此在<div id="root"> </ div>之后,我们将在public库中使用index.html文件

<!DOCTYPE html>
<html lang="en"><head><!-- Stuff --></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="https://apis.google.com/js/api.js"></script><!-- Stuff --></body>
</html>

This will give us access to window.gapi which we’ll use to connect to the Sheets API. For more information on it, head over to Google’s Docs.

这将使我们能够访问window.gapi ,我们将使用它来连接到Sheets API。 有关更多信息,请访问Google的文档 。

数据 (The Data)

Now that we have access to the API, let’s establish the connection to it. The best place to do that would be inside the componentDidMount lifecycle of the CarList component we created earlier. Let’s head over there.

现在我们已经可以访问该API,让我们建立与其的连接。 最好的选择是在我们之前创建的CarList组件的componentDidMount生命周期内。 我们去那边。

componentDidMount() {// 1. Load the JavaScript client library.window.gapi.load("client", this.initClient);
}

window.gapi.load accepts a callback so our initClient function looks like this:

window.gapi.load接受回调,因此我们的initClient函数如下所示:

initClient = () => {// 2. Initialize the JavaScript client library.window.gapi.client.init({apiKey: config.apiKey,// Your API key will be automatically added to the Discovery Document URLs.discoveryDocs: config.discoveryDocs}).then(() => {// 3. Initialize and make the API request.load(this.onLoad);});
};

A few things are introduced here. config is coming from the config.js file we created earlier, so don’t forget to do import config from “../config”; at the top of the CarList.js file.

这里介绍一些事情。 config来自我们之前创建的config.js文件,因此不要忘记import config from “../config”;CarList.js文件的顶部。

load is a function that we’ll be creating now. It will be in charge of connecting to the right spreadsheet, formatting the data correctly, and returning it to the component within the this.onLoad callback (or returning an error if we messed something up).

load是我们现在要创建的函数。 它将负责连接到正确的电子表格,正确格式化数据,并将其返回到this.onLoad回调中的组件(或者如果我们搞砸了则返回错误)。

I wanted to separate that logic from the component to keep the files small and fairly readable. Let’s create a new folder called helpers inside src and put a spreadsheet.js file in there.

我想将该逻辑与组件分开,以使文件更小且更易读。 让我们在src创建一个名为helpers的新文件夹,然后在其中放置一个spreadsheet.js

import config from "../config";
/*** Load the cars from the spreadsheet* Get the right values from it and assign.*/
export function load(callback) {window.gapi.client.load("sheets", "v4", () => {window.gapi.client.sheets.spreadsheets.values.get({spreadsheetId: config.spreadsheetId,range: "Sheet1!A4:T"}).then(response => {const data = response.result.values;
const cars = data.map(car => ({year: car[0],make: car[1],model: car[2]})) || [];
callback({cars});},response => {callback(false, response.result.error);});});
}

So here we’re invoking the sheets API and getting values from the spreadsheet by passing the spreadsheetId and the range . The promise returns two responses: one if there is data and one if there is an error. The response values are an array of arrays where each one is a row within the spreadsheet.

因此,在这里,我们要调用工作表API,并通过传递spreadsheetIdrange从电子表格中获取值。 承诺返回两个响应:一个响应(如果有数据)和一个错误(有错误)。 响应值是一个数组数组,其中每个都是电子表格中的一行。

显示器 (The Display)

Now that we have data back inside the CarList component, we can start setting up the display for it. Inside the initClient function, we had the load(this.onLoad) function, so let’s pick up there.

现在我们已经有数据返回到CarList组件内部,我们可以开始为其设置显示了。 在initClient函数内部,我们有load(this.onLoad)函数,因此让我们开始学习。

onLoad = (data, error) => {if (data) {const cars = data.cars;this.setState({ cars });} else {this.setState({ error });}
};

If the load function within spreadsheet.js returns data, we set the cars state to that data. Otherwise we set an error state to show to our users that something went wrong.

如果spreadsheet.js .js中的load函数返回数据,则将cars状态设置为该数据。 否则,我们将设置一个error状态,以向用户显示出了问题。

默认状态 (Default state)

Since data won’t be available instantly, we need to set up a default state for our component.

由于无法立即获得数据,因此我们需要为组件设置默认状态。

state = {cars: [],error: null
}

渲染 (Render)

Now inside the render function we can display the state:

现在,在render函数中,我们可以显示状态:

render() {const { cars, error } = this.state;if (error) {return <div>{this.state.error}</div>;}return (<ul>{cars.map((car, i) => (<li key={i}>{car.year} {car.make} {car.model}</li>))}</ul>);
}

Here we’re destructuring the state (ES6 FTW ??) and first checking if there is an error. If not, we’re mapping over the cars and displaying them in an unordered list.

在这里,我们要解构状态(ES6 FTW ??),并首先检查是否存在错误。 如果没有,我们将在汽车上绘制地图,并将其显示在无序列表中。

部署方式 (Deployment)

Now that we have our super beautiful list of cars Doug has reviewed, we can go ahead and share it with the world. Since it will be a static website, I am going to deploy it to Netlify using their CLI. For that we’re going to stop our localhost and run the following commands:

现在我们有了道格已审查的超级精美汽车清单,我们可以继续与世界分享。 由于它将是一个静态网站,因此我将使用其CLI将其部署到Netlify 。 为此,我们将停止本地主机并运行以下命令:

yarn build

This will create a build folder within the application which will be production ready. Now all you have to do is:

这将在应用程序中创建一个准备就绪的build文件夹。 现在您要做的就是:

npm install netlify-cli -g
netlify deploy

When it asks, make sure you put in build as the Path to deploy? (current dir) .

在询问时,请确保将build作为Path to deploy? (current dir) Path to deploy? (current dir)

Netlify is going to do its thing and show you the final URL (mine is https://laughing-yonath-118f58.netlify.com ?)

Netlify将执行其操作并向您显示最终URL(我的网址是https://laughing-yonath-118f58.netlify.com吗?)

If you try to access the one you created, you’ll see an error in your console because your URL wasn’t added to the Google API console. Go ahead and add the URL you need, and after that everything should be working as expected.

如果您尝试访问自己创建的控制台,则会在控制台中看到错误消息,因为您的网址未添加到Google API控制台中。 继续并添加所需的URL,然后一切都将按预期工作。

结束 (The End)

I hope all of this made sense. You can now work your magic on adding features to that list such as sorting, filtering, pagination, search, comparison, and so on. And when Doug adds another car to that list, the app will be automatically updated with the new information.

我希望所有这些都是有道理的。 现在,您可以发挥神奇的作用,向该列表添加功能,例如排序,过滤,分页,搜索,比较等等。 当道格将另一辆车添加到该列表时,该应用程序将自动更新为新信息。

If this tutorial made sense, give it a ?? and share it with a friend. If you want to tell me it sucked or you have any more questions, comment below or yell at me on Twitter, I really don’t mind. If Doug is reading this, hey Doug ??!

如果本教程有意义,请给它一个? 并与朋友分享。 如果您想告诉我它很烂,或者您还有其他问题,请在下面评论或在Twitter上对我大喊,我真的不介意。 如果Doug正在阅读此内容,则嘿Doug ??!

翻译自: https://www.freecodecamp.org/news/how-to-deploy-a-react-application-to-netlify-that-reads-from-a-google-sheet-97a015806c47/

react数据从本地读取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode743. 网络延迟时间(迪杰斯特拉算法)

有 N 个网络节点&#xff0c;标记为 1 到 N。 给定一个列表 times&#xff0c;表示信号经过有向边的传递时间。 times[i] (u, v, w)&#xff0c;其中 u 是源节点&#xff0c;v 是目标节点&#xff0c; w 是一个信号从源节点传递到目标节点的时间。 现在&#xff0c;我们从某个…

在线python视频教程_【好程序员】2019 Python全套视频教程2

2019千锋好程序员全新Python教程&#xff0c;深入浅出的讲解Python语言的基础语法&#xff0c;注重基本编程能力训练&#xff0c;深入解析面向对象思想&#xff0c;数据类型和变量、运算符、流程控制、函数、面向对象、模块和包、生成器和迭代器。教程列表&#xff1a;千锋Pyth…

洛谷——P1546 最短网络 Agri-Net

P1546 最短网络 Agri-Net 题目背景 农民约翰被选为他们镇的镇长&#xff01;他其中一个竞选承诺就是在镇上建立起互联网&#xff0c;并连接到所有的农场。当然&#xff0c;他需要你的帮助。 题目描述 约翰已经给他的农场安排了一条高速的网络线路&#xff0c;他想把这条线路共享…

漫谈单点登录(SSO)(淘宝天猫)(转载)

1. 摘要 &#xff08; 注意&#xff1a;请仔细看下摘要&#xff0c;留心此文是否是您的菜&#xff0c;若浪费宝贵时间&#xff0c;深感歉意&#xff01;&#xff01;&#xff01;&#xff09; SSO这一概念由来已久&#xff0c;网络上对应不同场景的成熟SSO解决方案比比皆是&…

mysql mdl 锁_MySQL MDL锁

MDL全称为metadata lock&#xff0c;即元数据锁。MDL锁主要作用是维护表元数据的数据一致性&#xff0c;在表上有活动事务(显式或隐式)的时候&#xff0c;不可以对元数据进行写入操作。因此从MySQL5.5版本开始引入了MDL锁&#xff0c;来保护表的元数据信息&#xff0c;用于解决…

Card Game Again CodeForces - 818E (双指针)

大意: 给定序列, 求多少个区间积被k整除. 整除信息满足单调性, 显然双指针. 具体实现只需要考虑k的素数向量, 对每一维维护个指针即可. 这题看了下cf其他人的做法, 发现可以直接暴力, 若当前的前缀积模k为0, 暴力向前求出第一个后缀积为0的位置即可, 复杂度是$O(n)$的并且相当好…

pacf和acf_如何通过Wordpress API,ACF和Express.js使Wordpress更加令人兴奋

pacf和acfby Tyler Jackson泰勒杰克逊(Tyler Jackson) 如何通过Wordpress API&#xff0c;ACF和Express.js使Wordpress更加令人兴奋 (How to make Wordpress more exciting with the Wordpress API, ACF, & Express.js) I’ve been working with Wordpress since it’s pr…

python运行出现数据错误_Python运行出错情况

1、错误内容&#xff1a;You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory str). It is highly recommended that you instead just switch your application to Unicode strings.错误描述&#x…

leetcode95. 不同的二叉搜索树 II(递归)

给定一个整数 n&#xff0c;生成所有由 1 ... n 为节点所组成的 二叉搜索树 。示例&#xff1a;输入&#xff1a;3 输出&#xff1a; [[1,null,3,2],[3,2,null,1],[3,1,null,null,2],[2,1,3],[1,null,2,null,3] ] 解释&#xff1a; 以上的输出对应以下 5 种不同结构的二叉搜索树…

数据结构探险系列—栈篇-学习笔记

数据结构探险—栈篇 什么是栈&#xff1f; 古代栈就是牲口棚的意思。 栈是一种机制&#xff1a;后进先出 LIFO&#xff08;last in first out&#xff09; 电梯 栈要素空栈。栈底&#xff0c;栈顶。没有元素的时候&#xff0c;栈顶和栈底指向同一个元素&#xff0c;如果加入新元…

MYSQL远程登录权限设置 ,可以让Navicat远程连接服务器的数据库

Mysql默认关闭远程登录权限&#xff0c;如下操作允许用户在任意地点登录&#xff1a;1. 进入mysql&#xff0c;GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY WITH GRANT OPTION;IDENTIFIED BY后跟的是密码&#xff0c;可设为空。2. FLUSH privileges; 更新Mysql为了安…

time series 时间序列 | fractional factorial design 部分要因试验设计

作业&#xff1a; 1) A plot of data from a time series, which shows a cyclical pattern – please show a time series plot and identify the length of the major cycle. 2) Data from a full factorial or fractional factorial experiment with at least 2 factors –…

如何在Go中编写防弹代码:不会失败的服务器工作流程

by Tal Kol通过塔尔科尔 如何在Go中编写防弹代码&#xff1a;不会失败的服务器工作流程 (How to write bulletproof code in Go: a workflow for servers that can’t fail) From time to time you may find yourself facing a daunting task: building a server that really …

越狱第一至五季/全集迅雷下载

越狱 第一季 Prison Break Season 1 (2005) 本季看点&#xff1a;迈克尔斯科菲尔德是一头陷于绝境欲拼死一搏的怒狮——他的哥哥林肯巴罗斯被认定犯有谋杀罪被投入了福克斯河监狱的死囚牢。虽然所有的证据都指出林肯就是凶手&#xff0c;迈克尔坚信兄长是无辜的。林肯的死刑执行…

leetcode面试题 16.19. 水域大小(深度优先搜索)

你有一个用于表示一片土地的整数矩阵land&#xff0c;该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小&#xff0c;返回值需要从小到大排序。 …

java -jar 默认参数_JAVA入门学习指南,建议收藏

如果你不懂Java 并且想认真学习接触了解一下Java的语法&#xff0c;建议把这篇文章收藏了&#xff0c;多看几遍&#xff0c;应该可以初步掌握Java 大部分基础的语法 。 让我们出发吧&#xff01;ps:本文有点长&#xff0c;耐心阅读 。〇&#xff0c;编程环境工程项目推荐使用ID…

【RabbitMQ】 WorkQueues

消息分发 在【RabbitMQ】 HelloWorld中我们写了发送/接收消息的程序。这次我们将创建一个Work Queue用来在多个消费者之间分配耗时任务。 Work Queues&#xff08;又称为&#xff1a;Task Queues&#xff09;的主要思想是&#xff1a;尽可能的减少执行资源密集型任务时的等待时…

python matplotlib库安装出错_使用pip install Matplotlib时出现内存错误

我使用的是Python2.7&#xff0c;如果我试图安装Matplotlib&#xff0c;如果我使用“pip install Matplotlib”&#xff0c;就会出现这个错误Exception:Traceback (most recent call last):File "/usr/local/lib/python2.7/dist-packages/pip/basecommand.py", line …

笑看职场什么程序员才抢手,什么样的程序员涨薪多?

​程序员&#xff0c;怎么才算合格&#xff0c;不好说吧&#xff1b;他就像销售一样&#xff0c;一名销售员&#xff0c;比如网络销售卖茶叶&#xff0c;他卖茶叶很厉害呀&#xff0c;可是你让他去销售房地产&#xff0c;就算他有点销售的基础&#xff0c;也要重新去学怎么销售…

Android画布Canvas裁剪clipRect,Kotlin

Android画布Canvas裁剪clipRect&#xff0c;Kotlin private fun mydraw() {val originBmp BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)val newBmp Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.A…