<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Axios - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Axios - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 11 Jul 2026 08:07:05 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/tag/axios/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 如何使用 React、React Hooks 和 Axios 进行 CRUD 操作 ]]>
                </title>
                <description>
                    <![CDATA[ 如果你正在使用React，理解和实现API请求可能是相当困难的。 所以在这篇文章中，我们将通过使用React、React Hooks、React Router和Axios实现CRUD操作来学习这一切。 让我们深入了解一下。 如何安装Node和npm 首先，让我们在系统中安装Node。我们将主要用它来执行我们的JavaScript代码。 去官方网站下载Node，https://nodejs.org/en/。 你还需要node包管理器 ，如npm，它是内建在Node上的。你可以用它来为你的JavaScript应用程序安装包。幸运的是，Node自带npm，所以你不需要单独下载它。 一旦它们都完成了，打开你的终端或命令提示符，输入node -v。这将检查你有哪个版本的Node。 如何创建你的React应用 为了创建你的React应用，在终端输入 npx create-react-app <你的应用程序名称>， 或者本例中的**npx create-react-app**react-crud**。 你会看到软件包正在被安装。 一旦软件包安装完毕，进入项目文件夹，输入npm st ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-perform-crud-operations-using-react/</link>
                <guid isPermaLink="false">645859f60f634b0716652bb9</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React Hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Axios ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Fri, 05 May 2023 11:10:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2023/05/React-CRUD-Operations-using-React-and-React-Hooks-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/how-to-perform-crud-operations-using-react/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Perform CRUD Operations using React, React Hooks, and Axios</a>
      </p><!--kg-card-begin: markdown--><p>如果你正在使用React，理解和实现API请求可能是相当困难的。</p>
<p>所以在这篇文章中，我们将通过使用React、React Hooks、React Router和Axios实现CRUD操作来学习这一切。</p>
<p>让我们深入了解一下。</p>
<h2 id="nodenpm">如何安装Node和npm</h2>
<p>首先，让我们在系统中安装Node。我们将主要用它来执行我们的JavaScript代码。</p>
<p>去官方网站下载Node，<a href="https://nodejs.org/en/">https://nodejs.org/en/</a>。</p>
<p>你还需要<strong>node包管理器</strong>，如npm，它是内建在Node上的。你可以用它来为你的JavaScript应用程序安装包。幸运的是，Node自带npm，所以你不需要单独下载它。</p>
<p>一旦它们都完成了，打开你的终端或命令提示符，输入<code>node -v</code>。这将检查你有哪个版本的Node。</p>
<h2 id="react">如何创建你的React应用</h2>
<p>为了创建你的React应用，在终端输入 <strong><strong><code>npx create-react-app &lt;你的应用程序名称&gt;</code></strong></strong>， 或者本例中的**<code>npx create-react-app**react-crud</code>**。</p>
<p>你会看到软件包正在被安装。</p>
<p>一旦软件包安装完毕，进入项目文件夹，输入<code>npm start</code>。</p>
<p>你会看到默认的React模板，像这样：</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-124754.png" alt="默认的 React Boilerplate 模板" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>默认的 React Boilerplate 模板</figcaption>
</figure>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-124858.png" alt="我们的 App.js文件" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>我们的 App.js文件</figcaption>
</figure>
<h2 id="reactsemanticui">如何为React安装Semantic UI包（库）</h2>
<p>让我们在我们的项目中安装Semantic UI React软件包。Semantic UI是一个为React制作的UI库，它有预建的UI组件，比如表格、按钮和许多功能。</p>
<p>你可以使用下面的一个命令来安装它，这取决于你的包管理器。</p>
<pre><code class="language-bash">yarn add semantic-ui-react semantic-ui-css
</code></pre>
<p>对于使用 Yarn 包管理器</p>
<pre><code class="language-bash">npm install semantic-ui-react semantic-ui-css
</code></pre>
<p>对于使用 NPM 包管理器</p>
<p>同时，在你的应用程序的主入口文件中导入该库，也就是index.js。</p>
<pre><code class="language-js">import 'semantic-ui-css/semantic.min.css'
</code></pre>
<p>在你的index.js文件中粘贴上面一行内容。</p>
<h2 id="crud"><strong>如何构建你的CRUD应用</strong></h2>
<p>现在，让我们开始使用React构建我们的CRUD应用。</p>
<p>首先，我们要给我们的应用程序添加一个标题。</p>
<p>在我们的app.js文件中，添加一个标题，像这样：</p>
<pre><code>import './App.css';

function App() {
  return (
    &lt;div&gt;
      React Crud Operations
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p>在我们的应用程序中添加一个标题</p>
<p>现在，让我们确保它居中。</p>
<p>给父级div一个classname，即main。在App.css文件中，我们将使用Flexbox来使标题居中。</p>
<pre><code>import './App.css';

function App() {
  return (
    &lt;div className="main"&gt;
      React Crud Operations
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p>app.js文件，在父 div 中的 className 为main的css定义。</p>
<pre><code>.main{
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
</code></pre>
<p>我们的 app.css 文件</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-130340.png" alt="Screenshot-2021-07-24-130340" width="600" height="400" loading="lazy"></p>
<p>现在我们的标题已经完全居中了。</p>
<p>为了让它看起来更好一些，我们需要使它加粗，并添加一些很酷的字体。要做到这一点，我们将在我们的标题周围使用标题标签，像这样：</p>
<pre><code>import './App.css';

function App() {
  return (
    &lt;div className="main"&gt;
      &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p>让我们从 Google Font导入一种字体. 从 <a href="https://fonts.google.com/">https://fonts.google.com/</a>选择一种。</p>
<p>选择任何你喜欢的字体，但我将使用Montserrat字体家族。</p>
<p>在App.css文件中导入你选择的字体，像这样：</p>
<pre><code>@import url('https://fonts.googleapis.com/css2?family=Montserrat&amp;display=swap');
</code></pre>
<p>现在，让我们改变标题的字体。</p>
<pre><code>&lt;div className="main"&gt;
      &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
    &lt;/div&gt;
</code></pre>
<p>给 <code>h2</code>一个 <code>lassName</code> 为 <code>main-header</code>，就像上面。</p>
<p>然后，在你的 App.css文件，添加font family：</p>
<pre><code>.main-header{
  font-family: 'Montserrat', sans-serif;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-132749.png" alt="Screenshot-2021-07-24-132749" width="600" height="400" loading="lazy"></p>
<p>现在你会看到改变后的标题。</p>
<h2 id="crud">如何创建你的CRUD组件</h2>
<p>让我们创建四个CRUD组件，它们将是创建、读取、更新和删除。</p>
<p>在我们的src文件夹中，创建一个名为组件的文件夹。在这个文件夹中，创建三个文件--创建、读取和更新。对于删除，我们不需要任何额外的组件。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133242.png" alt="Screenshot-2021-07-24-133242" width="600" height="400" loading="lazy"></p>
<p>现在，让我们来实现这些。</p>
<p>但为此，我们需要使用Mock API。这些API将向我们将要创建的假服务器发送数据，这只是为了学习的目的。</p>
<p>所以，请前往 <a href="https://mockapi.io/">https://mockapi.io/</a> ，创建账号。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133456.png" alt="MockAPI" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>MockAPI</figcaption>
</figure>
<p>通过点击<code>(plus)加号</code>按钮创建一个项目。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133553.png" alt="Screenshot-2021-07-24-133553" width="600" height="400" loading="lazy"></p>
<p>点击<code>(plus)加号</code>按钮，创建一个新的项目。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133702.png" alt="Screenshot-2021-07-24-133702" width="600" height="400" loading="lazy"></p>
<p>添加你的项目名称，然后点击<code>(create)创建</code>按钮。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133748.png" alt="Screenshot-2021-07-24-133748" width="600" height="400" loading="lazy"></p>
<p>现在，通过点击 <code>(NEW RESOURCE)新资源</code> 按钮创建一个新资源。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-133847.png" alt="Screenshot-2021-07-24-133847" width="600" height="400" loading="lazy"></p>
<p>它将要求你提供<code>(RESOURCE name)资源名称</code>，所以输入你想使用的名称。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-134009.png" alt="Screenshot-2021-07-24-134009" width="600" height="400" loading="lazy"></p>
<p>删除额外的字段，<code>如姓名(name)、头像(avatar)或创建时间(createdAt）</code>，因为我们将不需要这些。然后，点击<code>创建(create)</code>。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-134140.png" alt="Screenshot-2021-07-24-134140" width="600" height="400" loading="lazy"></p>
<p>现在，我们已经创建了我们的 <code>fake API(假API)</code>，我把它命名为fakeData。</p>
<p>点击fakeData，你会看到API在一个新的标签中打开。现在的数据库是空的。</p>
<h2 id="createcomponent">如何为(create Component)创建组件创建一个表格</h2>
<p>让我们使用Semantic UI库中的一个表单。</p>
<p>前往Semantic React，在左边的搜索栏中搜索Form。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-134532.png" alt="Screenshot-2021-07-24-134532" width="600" height="400" loading="lazy"></p>
<p>你会看到一个像这样的表格，点击左上方的 <code>试试(Try it)</code>，就可以得到代码。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-134654.png" alt="Screenshot-2021-07-24-134654" width="600" height="400" loading="lazy"></p>
<p>复制这段代码并将其粘贴到你的Create.js文件中，像这样：</p>
<pre><code>import React from 'react'
import { Button, Checkbox, Form } from 'semantic-ui-react'

const Create = () =&gt; (
    &lt;Form&gt;
        &lt;Form.Field&gt;
            &lt;label&gt;First Name&lt;/label&gt;
            &lt;input placeholder='First Name' /&gt;
        &lt;/Form.Field&gt;
        &lt;Form.Field&gt;
            &lt;label&gt;Last Name&lt;/label&gt;
            &lt;input placeholder='Last Name' /&gt;
        &lt;/Form.Field&gt;
        &lt;Form.Field&gt;
            &lt;Checkbox label='I agree to the Terms and Conditions' /&gt;
        &lt;/Form.Field&gt;
        &lt;Button type='submit'&gt;Submit&lt;/Button&gt;
    &lt;/Form&gt;
)

export default Create;
</code></pre>
<p>在你的app.js文件中导入创建组件(Create Component)。</p>
<pre><code>import './App.css';
import Create from './components/create';

function App() {
  return (
    &lt;div className="main"&gt;
      &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
      &lt;div&gt;
        &lt;Create/&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p>就像这样：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-135249.png" alt="Screenshot-2021-07-24-135249" width="600" height="400" loading="lazy"></p>
<p>但这里有一个问题--项目没有正确对齐，文本输入标签颜色是黑色的。所以，让我们来改变它。</p>
<p>在create.js文件中，给<strong>Form</strong>一个<code>create-form</code>的className。</p>
<pre><code>import React from 'react'
import { Button, Checkbox, Form } from 'semantic-ui-react'

const Create = () =&gt; (
    &lt;Form className="create-form"&gt;
        &lt;Form.Field&gt;
            &lt;label&gt;First Name&lt;/label&gt;
            &lt;input placeholder='First Name' /&gt;
        &lt;/Form.Field&gt;
        &lt;Form.Field&gt;
            &lt;label&gt;Last Name&lt;/label&gt;
            &lt;input placeholder='Last Name' /&gt;
        &lt;/Form.Field&gt;
        &lt;Form.Field&gt;
            &lt;Checkbox label='I agree to the Terms and Conditions' /&gt;
        &lt;/Form.Field&gt;
        &lt;Button type='submit'&gt;Submit&lt;/Button&gt;
    &lt;/Form&gt;
)

export default Create;
</code></pre>
<p>app.js</p>
<p>并在你的App.css文件中添加以下类。</p>
<pre><code>.create-form label{
  color: whitesmoke !important;
  font-family: 'Montserrat', sans-serif;
  font-size: 12px !important;
}
</code></pre>
<p>App.css</p>
<p>这个类将针对所有的表格字段标签并应用白烟的颜色。它还将改变字体并增加字体大小。</p>
<p>现在，在我们的主<code>className</code>中，添加一个flex-direction属性。这个属性将设置方向为列，所以主<code>className</code>中的每个元素都将水平对齐。</p>
<pre><code>.main{
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #212121;
  color: whitesmoke;
  flex-direction: column;
}
</code></pre>
<p>App.css</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-140141.png" alt="Screenshot-2021-07-24-140141" width="600" height="400" loading="lazy"></p>
<p>你可以看到，我们的表单现在看起来好多了。</p>
<p>接下来，让我们从表单字段中获取数据到我们的控制台(console)。为此，我们将使用React的<code>useState</code>钩子。</p>
<p>在我们的create.js文件中，从React中导入<code>useState</code>。</p>
<pre><code>import React, { useState } from 'react';
</code></pre>
<p>然后，为名字(first name)、姓氏(last name)和复选框(checkbox)创建状态。我们将这些状态初始化为空或假。</p>
<pre><code>import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'

export default function Create() {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [checkbox, setCheckbox] = useState(false);
    return (
        &lt;div&gt;
            &lt;Form className="create-form"&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;First Name&lt;/label&gt;
                    &lt;input placeholder='First Name' /&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;Last Name&lt;/label&gt;
                    &lt;input placeholder='Last Name' /&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;Checkbox label='I agree to the Terms and Conditions' /&gt;
                &lt;/Form.Field&gt;
                &lt;Button type='submit'&gt;Submit&lt;/Button&gt;
            &lt;/Form&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>你可以看到，这现在是作为一个函数组件。所以，我们需要把这个组件改成一个函数组件。这是因为我们只能在函数组件中使用钩子。</p>
<p>现在，让我们分别使用<code>setFirstName</code>、<code>setLastName</code>和<code>setCheckbox</code>属性来设置名字、姓氏和复选框。</p>
<pre><code>&lt;input placeholder='First Name' onChange={(e) =&gt; setFirstName(e.target.value)}/&gt;

&lt;input placeholder='Last Name' onChange={(e) =&gt; setLastName(e.target.value)}/&gt;

&lt;Checkbox label='I agree to the Terms and Conditions' onChange={(e) =&gt; setCheckbox(!checkbox)}/&gt;
</code></pre>
<p>我们正在获得名字(first name)、姓氏(last name)和复选框(checkout)的状态。</p>
<p>创建一个名为<code>postData</code>的函数，我们将用它来向API发送数据。在该函数中，写下这段代码。</p>
<pre><code>const postData = () =&gt; {
        console.log(firstName);
        console.log(lastName);
        console.log(checkbox);
}
</code></pre>
<p>我们在控制台中打印出名字(firstName)、姓氏(lastName)和复选框(checkbox)的值。</p>
<p>在(Submit button)提交按钮上，使用onClick事件调用这个函数，这样，每当我们按下提交按钮，这个函数就会被调用。</p>
<pre><code>&lt;Button onClick={postData} type='submit'&gt;Submit&lt;/Button&gt;
</code></pre>
<p>这里是 <em>create</em> 文件的全部代码。</p>
<pre><code>import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'

export default function Create() {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [checkbox, setCheckbox] = useState(false);
    const postData = () =&gt; {
        console.log(firstName);
        console.log(lastName);
        console.log(checkbox);
    }
    return (
        &lt;div&gt;
            &lt;Form className="create-form"&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;First Name&lt;/label&gt;
                    &lt;input placeholder='First Name' onChange={(e) =&gt; setFirstName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;Last Name&lt;/label&gt;
                    &lt;input placeholder='Last Name' onChange={(e) =&gt; setLastName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;Checkbox label='I agree to the Terms and Conditions' onChange={(e) =&gt; setCheckbox(!checkbox)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Button onClick={postData} type='submit'&gt;Submit&lt;/Button&gt;
            &lt;/Form&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>在名字和姓氏中输入一些数值，并勾选复选框。然后，点击提交按钮。你会看到控制台中打印出的数据是这样的。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-142717.png" alt="Screenshot-2021-07-24-142717" width="600" height="400" loading="lazy"></p>
<h2 id="axiosmockapis">如何使用Axios向Mock APIs发送请求</h2>
<p>让我们使用Axios来发送我们的表单数据到模拟服务器。</p>
<p>但首先，我们需要安装它。</p>
<p>只要输入<code>npm i axios</code>来安装这个包。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-174213.png" alt="Screenshot-2021-07-24-174213" width="600" height="400" loading="lazy"></p>
<p>软件包安装完毕后，让我们开始(create)创建操作。</p>
<p>在文件的顶部导入Axios。</p>
<pre><code>import axios from 'axios';
</code></pre>
<p>导入Axios</p>
<p>在<code>postData</code>函数中，我们将使用Axios来发送POST请求。</p>
<pre><code>const postData = () =&gt; {
        axios.post(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`, {
            firstName,
            lastName,
            checkbox
        })
    }
</code></pre>
<p>发送 Post 请求</p>
<p>如你所见，我们正在使用axios.post。在axios.post中, 我们有 API endpoint(接入点 请求地址), 这是我们之前创建的。然后，我们有被大括号包裹的表单字段。</p>
<p>当我们点击提交时，这个函数将被调用，它将向API服务器发布数据。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-174834.png" alt="Screenshot-2021-07-24-174834" width="600" height="400" loading="lazy"></p>
<p>输入你的名字(first name)，姓氏(last name)，并勾选复选框。点击提交。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-174930.png" alt="Screenshot-2021-07-24-174930" width="600" height="400" loading="lazy"></p>
<p>然后，你检查这个API的返回值，你会得到你的名字、姓氏，复选框为真的值，被包裹在一个对象中。</p>
<h2 id="">如何实现读取和更新操作</h2>
<p>为了开始(read)读取操作，我们需要创建一个读取页面。我们还需要React Router包来导航到不同的页面。</p>
<p>前往<a href="https://reactrouter.com/web/guides/quick-start">https://reactrouter.com/web/guides/quick-start</a>查看文档，同时运行 <code>npm i react-router-dom</code>进行安装。</p>
<p>安装完毕后，从React Router导入一些东西：</p>
<pre><code>import { BrowserRouter as Router, Route } from 'react-router-dom'
</code></pre>
<p>从<code>React Router</code>中导入<code>Router</code>和<code>Route</code>。</p>
<p>在我们的App.js中，把整个返回包成一个Router。这基本上意味着，无论这个Router里面有什么，都能在React中使用。</p>
<pre><code>import './App.css';
import Create from './components/create';
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    &lt;Router&gt;
      &lt;div className="main"&gt;
        &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
        &lt;div&gt;
          &lt;Create /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/Router&gt;
  );
}

export default App;
</code></pre>
<p>我们的App.js现在看起来会像上面的样子。</p>
<p>替换掉返回里面的Create，并添加以下代码。</p>
<pre><code>import './App.css';
import Create from './components/create';
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    &lt;Router&gt;
      &lt;div className="main"&gt;
        &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
        &lt;div&gt;
          &lt;Route exact path='/create' component={Create} /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/Router&gt;
  );
}

export default App;
</code></pre>
<p>在这里，我们使用Route组件作为Create。我们已经将Create的路径设置为'/create'。因此，如果我们进入<a href="http://localhost:3000/create">http://localhost:3000/create</a> ，我们将看到创建页面。</p>
<p>同样地，我们需要(read)读取和(update)更新的路由。</p>
<pre><code>import './App.css';
import Create from './components/create';
import Read from './components/read';
import Update from './components/update';
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    &lt;Router&gt;
      &lt;div className="main"&gt;
        &lt;h2 className="main-header"&gt;React Crud Operations&lt;/h2&gt;
        &lt;div&gt;
          &lt;Route exact path='/create' component={Create} /&gt;
        &lt;/div&gt;
        &lt;div style={{ marginTop: 20 }}&gt;
          &lt;Route exact path='/read' component={Read} /&gt;
        &lt;/div&gt;

        &lt;Route path='/update' component={Update} /&gt;
      &lt;/div&gt;
    &lt;/Router&gt;
  );
}

export default App;
</code></pre>
<p>因此，(read)读取和(update)更新路由，类似你上面看到的。</p>
<p>如果你前往 <a href="http://localhost:3000/read">http://localhost:3000/read</a>，会看到下面的：</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-180318.png" alt="Read Route" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Read Route</figcaption>
</figure>
<p>在<a href="http://localhost:3000/update">http://localhost:3000/update</a> 网址，我们可以看到更新组件（Update Component），像这样：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-180440.png" alt="Screenshot-2021-07-24-180440" width="600" height="400" loading="lazy"></p>
<h3 id="">读取操作</h3>
<p>对于读取操作，我们将需要一个表组件。因此，前往React Semantic UI，并使用库中的一个表。</p>
<pre><code>import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
    return (
        &lt;div&gt;
            &lt;Table singleLine&gt;
                &lt;Table.Header&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.HeaderCell&gt;Name&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Registration Date&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;E-mail address&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Premium Plan&lt;/Table.HeaderCell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Header&gt;

                &lt;Table.Body&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.Cell&gt;John Lilki&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;September 14, 2013&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;jhlilk22@yahoo.com&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;No&lt;/Table.Cell&gt;
                    &lt;/Table.Row&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.Cell&gt;Jamie Harington&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;January 11, 2014&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;jamieharingonton@yahoo.com&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;Yes&lt;/Table.Cell&gt;
                    &lt;/Table.Row&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.Cell&gt;Jill Lewis&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;May 11, 2014&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;jilsewris22@yahoo.com&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;Yes&lt;/Table.Cell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Body&gt;
            &lt;/Table&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>Read.js</p>
<p>在这里，你可以看到我们有一个带有一些假数据(dummy data)的表。但我们只需要一个表行。所以，让我们删除其他的。</p>
<pre><code>import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
    return (
        &lt;div&gt;
            &lt;Table singleLine&gt;
                &lt;Table.Header&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.HeaderCell&gt;Name&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Registration Date&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;E-mail address&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Premium Plan&lt;/Table.HeaderCell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Header&gt;

                &lt;Table.Body&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.Cell&gt;John Lilki&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;September 14, 2013&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;jhlilk22@yahoo.com&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;No&lt;/Table.Cell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Body&gt;
            &lt;/Table&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>Read.js</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-182905.png" alt="Screenshot-2021-07-24-182905" width="600" height="400" loading="lazy"></p>
<p>这是“阅读”页面的输出。我们有一个有四列的表，但我们只需要三列。</p>
<p>删除多余的字段列，并像这样重新命名字段。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-183105.png" alt="Screenshot-2021-07-24-183105" width="600" height="400" loading="lazy"></p>
<p>这就是我们的阅读页面现在的样子：</p>
<pre><code>import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
    return (
        &lt;div&gt;
            &lt;Table singleLine&gt;
                &lt;Table.Header&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.HeaderCell&gt;First Name&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Last Name&lt;/Table.HeaderCell&gt;
                        &lt;Table.HeaderCell&gt;Checked&lt;/Table.HeaderCell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Header&gt;

                &lt;Table.Body&gt;
                    &lt;Table.Row&gt;
                        &lt;Table.Cell&gt;Nishant&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;Kumar&lt;/Table.Cell&gt;
                        &lt;Table.Cell&gt;Yes&lt;/Table.Cell&gt;
                    &lt;/Table.Row&gt;
                &lt;/Table.Body&gt;
            &lt;/Table&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>Read.js</p>
<p>现在，让我们发送GET请求，从API获得数据。</p>
<p>当我们的应用程序加载时，我们需要这些数据。所以，我们要使用<code>useEffect</code>钩子(hook)。</p>
<pre><code>import React, { useEffect } from 'react';

 useEffect(() =&gt; {
       
 }, [])
</code></pre>
<p>useEffect钩子(hook)</p>
<p>创建一个包含传入数据的状态。这将是一个数组。</p>
<pre><code>import React, { useEffect, useState } from 'react';

const [APIData, setAPIData] = useState([]);
useEffect(() =&gt; {
       
}, [])
</code></pre>
<p>APIData state 来存储API传入的数据</p>
<p>在<code>useEffect</code>钩子(hook)中，让我们发送GET请求。</p>
<pre><code> useEffect(() =&gt; {
        axios.get(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`)
            .then((response) =&gt; {
                setAPIData(response.data);
            })
    }, [])
</code></pre>
<p>因此，我们使用axios.get来向API发送GET请求。然后，如果请求被满足，我们就在我们的_APIData_状态中设置响应数据。</p>
<p>现在，让我们根据API数据来映射我们的表行。</p>
<p>我们将使用Map函数来做这件事。它将对数组进行迭代，并在输出中显示数据。</p>
<pre><code>&lt;Table.Body&gt;
  {APIData.map((data) =&gt; {
     return (
       &lt;Table.Row&gt;
          &lt;Table.Cell&gt;{data.firstName}&lt;/Table.Cell&gt;
           &lt;Table.Cell&gt;{data.lastName}&lt;/Table.Cell&gt;
           &lt;Table.Cell&gt;{data.checkbox ? 'Checked' : 'Unchecked'}&lt;/Table.Cell&gt;
        &lt;/Table.Row&gt;
   )})}
&lt;/Table.Body&gt;
</code></pre>
<p>我们根据API中的数据来映射firstName、lastName和checkbox。但我们的复选框有一点不同。我在这里使用了一个三元操作符（'?'）。如果data.checkbox为真，输出将是Checked，否则将是Unchecked。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-184955.png" alt="Read.js 输出" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Read.js 输出</figcaption>
</figure>
<h3 id="update">更新(Update)操作</h3>
<p>再为更新创建一个标题，并在表行中为更新按钮创建一列。使用Semantic UI React的按钮。</p>
<pre><code>&lt;Table.HeaderCell&gt;Update&lt;/Table.HeaderCell&gt;

&lt;Table.Cell&gt; 
  &lt;Button&gt;Update&lt;/Button&gt;
&lt;/Table.Cell&gt;
</code></pre>
<p>创建(Update)更新按钮</p>
<p>现在，当我们点击这个按钮，我们应该被重定向到更新页面。为此，我们需要React Router的链接。</p>
<p>从React Router导入Link。并将更新按钮的表格单元格包装成Link标签。</p>
<pre><code>import { Link } from 'react-router-dom';

&lt;Link to='/update'&gt;
  &lt;Table.Cell&gt; 
     &lt;Button&gt;Update&lt;/Button&gt;
   &lt;/Table.Cell&gt;
&lt;/Link&gt;
</code></pre>
<p>为更新按钮添加链接(Link)</p>
<p>因此，如果我们点击更新按钮，我们将被重定向到更新页面。</p>
<p>为了更新列的数据，我们需要它们各自的ID，这从APIs获得。</p>
<p>创建一个名为 "setData "的函数。将其绑定到更新按钮上。</p>
<pre><code> &lt;Button onClick={() =&gt; setData()}&gt;Update&lt;/Button&gt;
</code></pre>
<p>现在，我们需要将数据作为参数传递给上面的函数。</p>
<pre><code> &lt;Button onClick={() =&gt; setData(data)}&gt;Update&lt;/Button&gt;
</code></pre>
<p>并在上面的的函数中，在控制台中打印这些数据。</p>
<pre><code>const setData = (data) =&gt; {
   console.log(data);
}
</code></pre>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-190515.png" alt="控制台的数据" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>控制台的数据</figcaption>
</figure>
<p>点击表中的更新按钮，并查看控制台。你会得到相应表字段的数据。</p>
<p>让我们把这些数据设置到localStorage中。</p>
<pre><code>const setData = (data) =&gt; {
        let { id, firstName, lastName, checkbox } = data;
        localStorage.setItem('ID', id);
        localStorage.setItem('First Name', firstName);
        localStorage.setItem('Last Name', lastName);
        localStorage.setItem('Checkbox Value', checkbox)
}
</code></pre>
<p>在本地存储中(Local Storage)设置数据</p>
<p>我们正在将我们的数据解构为id、firstName、lastName和checkbox，然后我们将这些数据设置到本地存储(Local Storage)。你可以使用本地存储(Local Storage)来在浏览器中的存储数据。</p>
<p>现在，在更新组件中，我们需要一个表单来进行更新操作。让我们复制(reate component)创建组件中的表单。只要把函数的名称从Create改为Update。</p>
<pre><code>import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
import axios from 'axios';

export default function Update() {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [checkbox, setCheckbox] = useState(false);

    return (
        &lt;div&gt;
            &lt;Form className="create-form"&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;First Name&lt;/label&gt;
                    &lt;input placeholder='First Name' onChange={(e) =&gt; setFirstName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;Last Name&lt;/label&gt;
                    &lt;input placeholder='Last Name' onChange={(e) =&gt; setLastName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;Checkbox label='I agree to the Terms and Conditions' onChange={(e) =&gt; setCheckbox(!checkbox)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Button type='submit'&gt;Update&lt;/Button&gt;
            &lt;/Form&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>我们的更新页面</p>
<p>在Update组件中创建一个`useEffect'钩子(hook)。我们将用它来获取我们之前存储在本地存储的数据。同时，为ID字段再创建一个状态(state)。</p>
<pre><code>const [id, setID] = useState(null);

useEffect(() =&gt; {
        setID(localStorage.getItem('ID'))
        setFirstName(localStorage.getItem('First Name'));
        setLastName(localStorage.getItem('Last Name'));
        setCheckbox(localStorage.getItem('Checkbox Value'))
}, []);
</code></pre>
<p>根据你的keys(字典，map 数据结构)从本地存储设置相应的数据。我们需要在表格字段中设置这些值。当更新页面加载时，它将自动填入这些字段。</p>
<pre><code>&lt;Form className="create-form"&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;First Name&lt;/label&gt;
                    &lt;input placeholder='First Name' value={firstName} onChange={(e) =&gt; setFirstName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;Last Name&lt;/label&gt;
                    &lt;input placeholder='Last Name' value={lastName} onChange={(e) =&gt; setLastName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;Checkbox label='I agree to the Terms and Conditions' checked={checkbox} onChange={(e) =&gt; setCheckbox(!checkbox)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Button type='submit'&gt;Update&lt;/Button&gt;
            &lt;/Form&gt;
</code></pre>
<p>设置表格字段的值</p>
<p>现在，如果我们点击阅读页面中的更新按钮，我们将被重定向到更新页面，在那里我们将看到所有根据数据自动填充的表单。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-193521.png" alt="更新页面" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>更新页面</figcaption>
</figure>
<p>现在，让我们创建更新请求来更新数据。</p>
<p>创建一个名为<code>updateAPIData</code>的函数。在这个函数中，我们将使用axios.put来发送一个PUT请求，以更新我们的数据。</p>
<pre><code>const updateAPIData = () =&gt; {
    axios.put(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`, {
        firstName,
         lastName,
         checkbox
	})
}
</code></pre>
<p>在这里，你可以看到我们在API端点上附加了一个id字段。</p>
<p>当我们点击表中的字段时，它的ID会被存储到本地存储器(Local Storage)中。而在更新页面，我们正在检索它。然后，我们将该ID存储在_<code>id</code>_状态中。</p>
<p>之后，我们将ID传递给端点。这使我们能够更新我们传递ID的字段。</p>
<p>将<code>updateAPIData</code>函数绑定到更新按钮上。</p>
<pre><code>&lt;Button type='submit' onClick={updateAPIData}&gt;Update&lt;/Button&gt;
</code></pre>
<p>将updateAPIData绑定到更新按钮上</p>
<p>点击读取页面中表格的更新按钮，改变你的姓氏（last name），然后点击更新页面中的更新按钮。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-194627.png" alt="更新字段" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>更新字段</figcaption>
</figure>
<p>回到“阅读”页面，或查看API。你会看到你的姓氏(last name)已被改变。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-194756.png" alt="The Mock API" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>The Mock API</figcaption>
</figure>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-194822.png" alt="我们的读取表格" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>我们的读取表格</figcaption>
</figure>
<h3 id="">删除操作</h3>
<p>在读取表(read table)中再添加一个Button，我们将用它来进行删除操作。</p>
<pre><code>&lt;Table.Cell&gt;
   &lt;Button onClick={() =&gt; onDelete(data.id)}&gt;Delete&lt;/Button&gt;
&lt;/Table.Cell&gt;
</code></pre>
<p>读取表中的删除按钮</p>
<p>创建一个名为 "onDelete "的函数，并将此函数绑定到删除按钮上。这个函数将在点击删除按钮时接收一个ID参数。</p>
<pre><code>const onDelete = (id) =&gt; {

}
</code></pre>
<p>The Delete Function</p>
<p>We are going to use axios.delete to delete the respective columns.</p>
<pre><code>const onDelete = (id) =&gt; {
  axios.delete(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`)
}
</code></pre>
<p>从API中删除字段</p>
<p>点击删除按钮并检查API。你会看到数据已经被删除。</p>
<p>我们需要在表被删除后获得该表的数据。</p>
<p>因此，创建一个函数来获得API数据。</p>
<pre><code>const getData = () =&gt; {
    axios.get(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`)
        .then((getData) =&gt; {
             setAPIData(getData.data);
         })
}
</code></pre>
<p>获取API数据</p>
<p>现在，在<code>onDelete</code>函数中，我们需要在删除一个字段后获得更新的数据。</p>
<pre><code>const onDelete = (id) =&gt; {
        axios.delete(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`)
     .then(() =&gt; {
        getData();
    })
}
</code></pre>
<p>删除一个字段后获得更新数据</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-201047.png" alt="读取表格" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>读取表格</figcaption>
</figure>
<p>因此，现在如果我们在任何字段上点击Delete，它将删除该字段并自动刷新表格。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-24-201423.png" alt="删除一个字段后读表" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>删除一个字段后读表</figcaption>
</figure>
<h2 id="crud">让我们对我们的CRUD应用程序做一些改进吧</h2>
<p>因此，当我们在Create页面发布我们的数据时，我们只是在模拟(mock)数据库中获得数据。当我们的数据在创建页面中被创建时，我们需要重定向到读取页面。</p>
<p>从React Router导入`useHistory'。</p>
<pre><code>import { useHistory } from 'react-router';
</code></pre>
<p>从React Router导入useHistory</p>
<p>创建变量<code>history</code>使用 <code>let</code>。</p>
<pre><code>let history = useHistory();
</code></pre>
<p>然后，使用history.push函数，在post API被调用后推送到阅读页面。</p>
<pre><code>const postData = () =&gt; {
        axios.post(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`, {
            firstName,
            lastName,
            checkbox
        }).then(() =&gt; {
            history.push('/read')
        })
    }
</code></pre>
<p>在发布API成功后推送到阅读页面</p>
<p>它将使用<code>useHistory</code>钩子(hook)推送到阅读页面。</p>
<p>对更新页面做同样的处理。</p>
<pre><code>import React, { useState, useEffect } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useHistory } from 'react-router';

export default function Update() {
    let history = useHistory();
    const [id, setID] = useState(null);
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [checkbox, setCheckbox] = useState(false);

    useEffect(() =&gt; {
        setID(localStorage.getItem('ID'))
        setFirstName(localStorage.getItem('First Name'));
        setLastName(localStorage.getItem('Last Name'));
        setCheckbox(localStorage.getItem('Checkbox Value'));
    }, []);

    const updateAPIData = () =&gt; {
        axios.put(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`, {
            firstName,
            lastName,
            checkbox
        }).then(() =&gt; {
            history.push('/read')
        })
    }
    return (
        &lt;div&gt;
            &lt;Form className="create-form"&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;First Name&lt;/label&gt;
                    &lt;input placeholder='First Name' value={firstName} onChange={(e) =&gt; setFirstName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;label&gt;Last Name&lt;/label&gt;
                    &lt;input placeholder='Last Name' value={lastName} onChange={(e) =&gt; setLastName(e.target.value)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Form.Field&gt;
                    &lt;Checkbox label='I agree to the Terms and Conditions' checked={checkbox} onChange={() =&gt; setCheckbox(!checkbox)}/&gt;
                &lt;/Form.Field&gt;
                &lt;Button type='submit' onClick={updateAPIData}&gt;Update&lt;/Button&gt;
            &lt;/Form&gt;
        &lt;/div&gt;
    )
}
</code></pre>
<p>Update.js</p>
<p>现在你知道如何使用React和React Hooks进行CRUD操作了吧！</p>
<p>另外，如果你想补充学习，你可以观看我在Youtube上的[React CRUD操作视频]（<a href="https://youtu.be/-ZMP8ZladIQ%EF%BC%89%E3%80%82">https://youtu.be/-ZMP8ZladIQ）。</a></p>
<blockquote>
<p><strong>学习愉快</strong></p>
</blockquote>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何在 React 中使用 Axios ]]>
                </title>
                <description>
                    <![CDATA[ 原文：How To Use Axios With React: The Definitive Guide (2021) [https://www.freecodecamp.org/news/how-to-use-axios-with-react/]，作者：Reed Barger [https://www.freecodecamp.org/news/author/reed/] 在本指南中，你将看到如何使用Axios.js和React，其中包括大量具有React hook的真实世界的例子。 你会看到为什么你应该使用Axios作为数据获取库，如何用React设置它，并使用它执行各种类型的HTTP请求。 然后，我们将触及更多的高级功能，例如创建Axios实例以实现可重用性、使用async-await来简化Axios，以及如何将Axios作为一个自定义Hook。 让我们直接开始吧！ 想要自己的副本?‬ 📄 点击这里下载PDF格式的小册子 [https://reedbarger.com/resources/react-axios-2021]（只需要5秒就能下载它）。 它包括这里所有的 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-use-axios-with-react/</link>
                <guid isPermaLink="false">625f848899ec7406219e6f03</guid>
                
                    <category>
                        <![CDATA[ Axios ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Wed, 20 Apr 2022 03:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/04/how-to-use-axios-with-react-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/how-to-use-axios-with-react/">How To Use Axios With React: The Definitive Guide (2021)</a>，作者：<a href="https://www.freecodecamp.org/news/author/reed/">Reed Barger</a></p><!--kg-card-begin: markdown--><p>在本指南中，你将看到如何使用Axios.js和React，其中包括大量具有React hook的真实世界的例子。</p>
<p>你会看到为什么你应该使用Axios作为数据获取库，如何用React设置它，并使用它执行各种类型的HTTP请求。</p>
<p>然后，我们将触及更多的高级功能，例如创建Axios实例以实现可重用性、使用async-await来简化Axios，以及如何将Axios作为一个自定义Hook。</p>
<p>让我们直接开始吧！</p>
<h3 id=""><strong>想要自己的副本?‬ 📄</strong></h3>
<p><strong><strong><a href="https://reedbarger.com/resources/react-axios-2021">点击这里下载PDF格式的小册子</a></strong></strong>（只需要5秒就能下载它）。</p>
<p>它包括这里所有的基本信息，是一个方便的PDF指南。</p>
<h2 id="">目录</h2>
<ul>
<li><a href="#what-is-axios">什么是Axios?</a></li>
<li><a href="#why-use-axios-in-react">为什么在React中使用Axios</a></li>
<li><a href="#how-to-set-up-axios-with-react">如何用React设置Axios</a></li>
<li><a href="#how-to-make-a-get-request">如何进行GET请求（检索数据）</a></li>
<li><a href="#how-to-make-a-post-request">如何进行POST请求（创建数据）</a></li>
<li><a href="#how-to-make-a-put-request">如何进行PUT请求（更新数据）</a></li>
<li><a href="#how-to-make-a-delete-request">如何提出DELETE请求（删除数据）</a></li>
<li><a href="#how-to-handle-errors-with-axios">如何处理Axios的错误</a></li>
<li><a href="#how-to-create-an-axios-instance">如何创建一个Axios实例</a></li>
<li><a href="#how-to-use-the-async-await-syntax-with-axios">如何使用Axios的Async-Await语法</a></li>
<li><a href="#how-to-create-a-custom-useaxios-hook">如何创建一个自定义的 <code>useAxios</code> Hook</a></li>
</ul>
<h2 id="what-is-axios">什么是Axios?</h2>
<p>Axios是一个HTTP客户端库，它允许你向一个给定的端点（endpoint）发出请求。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screen-Shot-2021-07-12-at-1.14.41-PM.png" alt="Screen-Shot-2021-07-12-at-1.14.41-PM" width="600" height="400" loading="lazy"></p>
<p>例如，这可能是一个外部API或你自己的后端Node.js服务器。</p>
<p>通过提出请求，你希望你的API能根据你提出的请求执行操作。</p>
<p>例如，如果你提出一个GET请求，你希望得到的数据能在你的应用程序中显示。</p>
<h2 id="why-use-axios-in-react">为什么在React中使用Axios</h2>
<p>有许多不同的库可以用来提出这些请求，那么为什么选择Axios呢？</p>
<p>以下<strong>五个理由</strong>说明了为什么你应该使用Axios作为你的客户端来进行HTTP请求。</p>
<ol>
<li>它有很好的默认值来处理JSON数据。与Fetch API等可选项不同，你通常不需要设置你的头文件。或执行繁琐的任务，如将你的请求体转换为JSON字符串</li>
<li>Axios有与任何HTTP方法相匹配的函数名称。要执行一个GET请求，你可以使用<code>.get()</code>方法。</li>
<li>Axios用更少的代码做更多的事情。与Fetch API不同，你只需要一个<code>.then()</code>回调来访问你请求的JSON数据。</li>
<li>Axios有更好的错误处理。Axios为你抛出400和500范围的错误。不像Fetch API，你必须检查状态代码并自己抛出错误。</li>
<li>Axios既可以在服务器上使用，也可以在客户端使用。如果你正在写一个Node.js应用程序，请注意Axios也可以在独立于浏览器的环境中使用。</li>
</ol>
<h2 id="how-to-set-up-axios-with-react">如何用React设置Axios</h2>
<p>在React中使用Axios是一个非常简单的过程。你需要三样东西：</p>
<ol>
<li>一个现有的React项目</li>
<li>用npm/yarn来安装Axios</li>
<li>一个用于发出请求的API端点</li>
</ol>
<p>创建一个新的React应用程序的最快捷的方法是访问<a href="https://react.new">react.new</a>网站。</p>
<p>如果你有一个现有的React项目，你只需要用npm（或任何其他包管理器）安装Adios。</p>
<pre><code class="language-bash">npm install axios
</code></pre>
<p>在本指南中，你将使用JSON Placeholder API来获取和改变帖子数据。</p>
<p>下面是你可以提出请求的所有不同路由(routes)的列表，以及每个路线的相应HTTP方法:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screen-Shot-2021-07-10-at-12.21.28-PM.png" alt="Screen-Shot-2021-07-10-at-12.21.28-PM" width="600" height="400" loading="lazy"></p>
<p>下面是一个快速的例子，说明你将使用Axios和你的API端点（endpoint）进行的所有操作——检索、创建、更新和删除帖子：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/axios-react.gif" alt="axios-react" width="600" height="400" loading="lazy"></p>
<h2 id="how-to-make-a-get-request">如何进行GET请求（检索数据）</h2>
<p>要获取数据或检索数据，要提出一个GET请求。</p>
<p>首先，你要对单个帖子进行请求。如果你看一下端点（endpoint），你将从<code>/posts</code>端点获得第一个帖子。</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts/1";

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    axios.get(baseURL).then((response) =&gt; {
      setPost(response.data);
    });
  }, []);

  if (!post) return null;

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>为了在挂载组件时执行这个请求， 你可以使用<code>useEffect</code>Hook。这涉及到导入Axios，使用<code>.get()</code>方法向你的端点（endpoint）发出GET请求，并使用<code>.then()</code>回调获得所有的响应数据。</p>
<p>响应被作为一个对象返回。数据（这里是一个带有<code>id</code>,<code>title</code>和<code>body</code>属性的帖子）被放在一个叫做<code>post</code>的状态中，在组件中显示。</p>
<p>请注意，你总是可以从响应中的<code>.data</code>属性中找到请求的数据。</p>
<h2 id="how-to-make-a-post-request">如何进行POST请求（创建数据）</h2>
<p>要创建新的数据，要发出一个POST请求。</p>
<p>根据API，这需要在<code>/posts</code>端点（endpoint）上执行。如果你看一下下面的代码，你会发现点击一个按钮可以创建一个帖子。</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts";

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    axios.get(`${baseURL}/1`).then((response) =&gt; {
      setPost(response.data);
    });
  }, []);

  function createPost() {
    axios
      .post(baseURL, {
        title: "Hello World!",
        body: "This is a new post."
      })
      .then((response) =&gt; {
        setPost(response.data);
      });
  }

  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
      &lt;button onClick={createPost}&gt;Create Post&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>当你点击按钮时，它会调用<code>createPost</code>函数。</p>
<p>为了用Axios进行POST请求，你使用<code>.post()</code>方法。作为第二个参数，你包括一个对象属性，指定你希望新的帖子是什么。</p>
<p>再一次，使用<code>.then()</code>回调来获取响应数据，用你请求的新帖子替换你得到的第一个帖子。</p>
<p>这与<code>.get()</code>方法非常相似，但你想要创建的新资源是作为API端点（endpoint）之后的第二个参数提供的。</p>
<h2 id="how-to-make-a-put-request">如何进行PUT请求（更新数据）</h2>
<p>要更新一个给定的资源，要提出一个PUT请求。</p>
<p>在这种情况下，你将更新第一个帖子。</p>
<p>为了做到这一点，你将再次创建一个按钮。但这一次，该按钮将调用一个函数来更新一个帖子:</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts";

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    axios.get(`${baseURL}/1`).then((response) =&gt; {
      setPost(response.data);
    });
  }, []);

  function updatePost() {
    axios
      .put(`${baseURL}/1`, {
        title: "Hello World!",
        body: "This is an updated post."
      })
      .then((response) =&gt; {
        setPost(response.data);
      });
  }

  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
      &lt;button onClick={updatePost}&gt;Update Post&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>在上面的代码中，你使用了Axios的PUT方法。和POST方法一样，你包括了你想在更新资源中的属性。</p>
<p>同样，使用<code>.then()</code>回调，你用返回的数据更新JSX。</p>
<h2 id="how-to-make-a-delete-request">如何进行DELETE请求（删除数据）</h2>
<p>最后，要删除一个资源，使用DELETE方法。</p>
<p>作为一个例子，我们将删除第一个帖子。</p>
<p>注意，你不需要第二个参数来执行这个请求。</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts";

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    axios.get(`${baseURL}/1`).then((response) =&gt; {
      setPost(response.data);
    });
  }, []);

  function deletePost() {
    axios
      .delete(`${baseURL}/1`)
      .then(() =&gt; {
        alert("Post deleted!");
        setPost(null)
      });
  }

  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
      &lt;button onClick={deletePost}&gt;Delete Post&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>在大多数情况下，你不需要从<code>.delete()</code>方法中返回的数据。</p>
<p>但在上面的代码中，<code>.then()</code>回调仍被用来确保你的请求被成功处理。</p>
<p>在上面的代码中，一个帖子被删除后，用户会被提醒它被成功删除。然后，帖子数据被清除出状态，将其设置为初始值<code>null</code>。</p>
<p>另外，一旦一个帖子被删除，就会在警告信息后立即显示文本“没有帖子”。</p>
<h2 id="如何处理Axios的错误">如何处理Axios的错误</h2>
<p>如何处理Axios的错误？</p>
<p>如果在发出请求时出现了错误怎么办？例如，你可能传递了错误的数据，向错误的端点（endpoint）发出了请求，或者出现了网络错误。</p>
<p>为了模拟一个错误，你将向一个不存在的API端点（endpoint）发送一个请求：<code>/posts/asdf</code>.</p>
<p>这个请求将返回一个<code>404</code>状态代码。</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const baseURL = "https://jsonplaceholder.typicode.com/posts";

export default function App() {
  const [post, setPost] = React.useState(null);
  const [error, setError] = React.useState(null);

  React.useEffect(() =&gt; {
    // invalid url will trigger an 404 error
    axios.get(`${baseURL}/asdf`).then((response) =&gt; {
      setPost(response.data);
    }).catch(error =&gt; {
      setError(error);
    });
  }, []);
  
  if (error) return `Error: ${error.message}`;
  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>在这种情况下，Axios不会执行<code>.then()</code>回调函数，而是抛出一个错误并运行<code>.catch()</code>回调函数。</p>
<p>在这个函数中，我们正在获取错误数据，并将其放入状态，以提醒我们的用户注意错误。因此，如果我们有一个错误，我们将显示该错误信息。</p>
<p>在这个函数中，错误数据被放在状态中，用来提醒用户注意错误。所以，如果有一个错误，就会显示一个错误信息。</p>
<p>当你运行这段代码的时候，你会看到这样的文字, "Error: Request failed with status code 404".</p>
<h2 id="how-to-create-an-axios-instance">如何创建一个Axios实例</h2>
<p>如果你看一下前面的例子，你会发现有一个<code>baseURL</code>，你用它作为Axios执行这些请求的端点（endpoint）的一部分。</p>
<p>然而，为每一个请求不断地编写<code>baseURL</code>是有点乏味的。你能不能让Axios记住你使用的<code>baseURL</code>？因为它总是涉及一个类似的端点。</p>
<p>事实上，你可以。如果你用<code>.create()</code>方法创建一个实例，Axios会记住<code>baseURL</code>，以及你可能想为每个请求指定的其他值，包括消息头（header）。</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const client = axios.create({
  baseURL: "https://jsonplaceholder.typicode.com/posts" 
});

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    client.get("/1").then((response) =&gt; {
      setPost(response.data);
    });
  }, []);

  function deletePost() {
    client
      .delete("/1")
      .then(() =&gt; {
        alert("Post deleted!");
        setPost(null)
      });
  }

  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
      &lt;button onClick={deletePost}&gt;Delete Post&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>上述配置对象中的一个属性是<code>baseURL</code>，你把端点（endpoint）传给它。</p>
<p><code>.create()</code>函数返回一个新创建的实例，在本例中它被称为<code>client</code>。</p>
<p>然后在未来，你可以使用所有与之前相同的方法，但你不必再将<code>baseURL</code>作为第一个参数。你只需要引用你想要的特定路由，例如，<code>/</code>，<code>/1</code>，等等。</p>
<h2 id="how-to-use-the-async-await-syntax-with-axios">如何使用Axios的Async-Await语法</h2>
<p>在JavaScript（包括React应用程序）中使用promises的一大好处是async-await语法。</p>
<p>Async-await允许你不使用<code>then</code>和<code>catch</code>回调函数的情况下写出更简洁的代码。另外，使用async-await的代码看起来很像同步代码，而且更容易理解。</p>
<p>但你如何使用Axios的async-await语法呢？</p>
<p>在下面的例子中，获取了帖子，但仍有一个按钮可以删除该帖子：</p>
<pre><code class="language-js">import axios from "axios";
import React from "react";

const client = axios.create({
  baseURL: "https://jsonplaceholder.typicode.com/posts" 
});

export default function App() {
  const [post, setPost] = React.useState(null);

  React.useEffect(() =&gt; {
    async function getPost() {
      const response = await client.get("/1");
      setPost(response.data);
    }
    getPost();
  }, []);

  async function deletePost() {
    await client.delete("/1");
    alert("Post deleted!");
    setPost(null);
  }

  if (!post) return "No post!"

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.body}&lt;/p&gt;
      &lt;button onClick={deletePost}&gt;Delete Post&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>然而在<code>useEffect</code>中，有一个<code>async</code>函数，叫做<code>getPost</code>。</p>
<p>让它成为<code>async</code>允许你使用<code>await</code>关键字来解决(resolve)GET请求，并在下一行将该数据设置为状态，而不需要<code>.then()</code>回调。</p>
<p>注意，<code>getPost</code>函数在被创建后立即被调用。</p>
<p>此外，<code>deletePost</code>函数现在是<code>async</code>，这是使用<code>await</code>关键字的要求，它可以解决(resolve)它返回的promise（每个Axios方法都会返回一个promise来解决(resolve)）。</p>
<p>在使用<code>await</code>关键字和DELETE请求后，用户会被提醒帖子被删除，并且帖子被设置为<code>null</code>。</p>
<p>正如你所看到的，async-await极大地简化了代码，你可以非常容易地将其用于Axios。</p>
<h2 id="how-to-create-a-custom-useaxios-hook">如何创建一个自定义的 `useAxios` Hook</h2>
<p>Async-await是一个简化代码的好方法，但你可以更进一步。</p>
<p>你可以用Axios创建你自己的自定义Hook，作为一个可重用的函数执行同样的操作，而不是使用<code>useEffect</code>在组件挂载时获取数据。</p>
<p>虽然你可以自己制作这个自定义Hook，但是有一个非常好的库可以给你一个自定义的<code>useAxios</code>钩子，叫做use-axios-client。</p>
<p>首先，安装该软件包：</p>
<pre><code>npm install use-axios-client
</code></pre>
<p>要使用Hook本身，请在组件的顶部从use-axios-client导入<code>useAxios</code>。</p>
<p>因为你不再需要<code>useEffect</code>，你可以删除React的导入。</p>
<pre><code class="language-js">import { useAxios } from "use-axios-client";

export default function App() {
  const { data, error, loading } = useAxios({
    url: "https://jsonplaceholder.typicode.com/posts/1"
  });

  if (loading || !data) return "Loading...";
  if (error) return "Error!";

  return (
    &lt;div&gt;
      &lt;h1&gt;{data.title}&lt;/h1&gt;
      &lt;p&gt;{data.body}&lt;/p&gt;
    &lt;/div&gt;
  ) 
}
</code></pre>
<p>现在你可以在应用程序组件的顶部调用<code>useAxios</code>，传入你想要请求的URL，钩子会返回一个对象，其中包含你需要处理不同状态的所有值。<code>loading</code>, <code>error</code>和解决(resolved)的<code>data</code>。</p>
<p>在执行这个请求的过程中，值<code>loading</code>将为真。如果有一个错误，你会想显示这个错误状态。否则，如果你有返回的数据，你可以在用户界面中显示它。</p>
<p>像这样的自定义Hook的好处是，它确实减少了代码，并从整体上简化了代码</p>
<p>如果你想用Axios获取更简单的数据，可以试试像这样的自定义<code>useAxios</code>钩子。</p>
<h2 id="">还有呢？</h2>
<p>恭喜你！你现在知道如何使用一个最强大的HTTP客户端库来支持你的React应用了。你现在知道如何使用最强大的HTTP客户端库之一来支持你的React应用程序。</p>
<p>我希望你从本指南中收获了很多。</p>
<p><a href="https://reedbarger.com/resources/react-axios-2021">记住，你可以将本指南下载为PDF格式的手册，以备将来参考。</a></p>
<h2 id="react">欢迎加入 React 训练营</h2>
<p><strong><a href="http://bit.ly/join-react-bootcamp">React 训练营</a></strong> 这本书把你应该知道的关于学习React的所有知识，综合在一起，包括视频、手册，还有特别的奖金。</p>
<p>收取<strong>已经成为React专家百名开发者</strong>的消息。他们已经找到自己梦想的工作，并掌控自己的未来。</p>
<p><a href="http://bit.ly/join-react-bootcamp"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/react-bootcamp-banner.png" alt="The React Bootcamp" width="600" height="400" loading="lazy"></a><br>
<em>请点击这里，当它开放时，你将得到通知</em></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
