FastAPI+React全栈开发19 React Hooks事件和状态

news/2024/7/15 20:16:49 标签: react.js, fastapi, javascript

Chapter04 Setting Up a React Workflow

19 React Hooks envents and state

FastAPI+React全栈开发19 React Hooks事件和状态

A great definition of React or its components is that it is, essentially, a function that converts a state to a user interface, a React component is literally a function, as we have seen, and it takes props as arguments. The output of the function (the component, really!) is a JSX element. Essentially, React hooks are functional constructs that enable us to tap into the life cycle of a component and mess with its state.

React或其组件的一个重要定义是,它本质上是一个将状态转换为用户界面的函数,React组件实际上是一个函数,正如我们所看到的,它接受props作为参数。函数的输出(实际上是组件!)是一个JSX元素。从本质上讲,React钩子是功能结构,它使我们能够进入组件的生命周期并扰乱其状态。

Creating stateful variables with useState

The first, and probably the most fundamental hook, is the useState hook, which enables us to maintain a certain state throughout our component. Let’s say that we want to maintain some kind of state in our one-page app, we want to set a budget limit and how much money we are willing to spend, so the website doesn’t try to lure us into even looking at those cars tha are just too expensive. We will make a simple textbox, set it to dispaly jsut numeric values, and hook it up with a state variable that we will aptly name budget. I have made quite a few changes to the App.js file, but we will go over it line by line.

第一个,可能也是最基本的钩子是useState钩子,它使我们能够在整个组件中维护特定的状态。假设我们想要在我们的单页应用中保持某种状态,我们想要设定预算限制和我们愿意花多少钱,这样网站就不会试图引诱我们去看那些太贵的车。我们将创建一个简单的文本框,将其设置为仅显示数值,并将其与一个状态变量连接起来,我们将恰当地将其命名为budget。我已经对App.js文件做了一些修改,但我们将逐行检查。

import Header from "./components/Header";
import Card from "./components/Card";
import {useState} from "react";

function App() {
    let data = [
        {id: 1, brand: "Fiat", color: "green", model: "500L", price: 7000, year: 2020,},
        {id: 2, brand: "Peugeot", color: "red", model: "5008", price: 8000, year: 2018,},
        {id: 3, brand: "Volkswagen", color: "white", model: "Golf 7", price: 8500, year: 2019,},
        {id: 4, brand: "Fiat", color: "green", model: "500L", price: 7000, year: 2020,},
        {id: 5, brand: "Peugeot", color: "red", model: "5008", price: 8000, year: 2018,},
        {id: 6, brand: "Volkswagen", color: "white", model: "Golf 7", price: 8500, year: 2019,},
    ]
    // 响应变量
    let [budget, setBudeget] = useState(4000)
    // 响应实际
    const onChangeHandler = (e) => {
        setBudeget(e.target.value)
    }

    return (
        <div className="App max-w-3xl mx-auto h-full">
            <Header/>
            {/*显示budget*/}
            <div className="border-2 border-yellow-500 my-5 p-3">
                Your current budget is:
                <span>{budget}</span>
            </div>
            {/*显示卡片*/}
            <div className="grid grid-cols-3 my-3 gap-3">
                {data.map(v => {
                    return (
                        <Card key={v.id} car={v}/>
                    )
                })}
            </div>
            {/*显示表单*/}
            <div className="bg-gray-300 rounded-md p-3">
                <label htmlFor="budget">Budget:</label>
                <input
                    type="number"
                    id="budget"
                    name="budget"
                    onChange={onChangeHandler}
                    min="300"
                    max="10000"
                    step="100"
                    value={budget}/>
            </div>
        </div>
    );
}

export default App;

Let’s see what we did here. First, we imported the useState hook from React. The useState hook, probably the simplest of them all, returns two values, a variable (which can be anything we want, an array or an object) and a function that sets the value for this state variable. Although you can use any legal JavaScript name, it is a good vonvention to use the name of the variable, in our case, budget, and the same name, prepended with set:setBudget. That’s all there is to it! With this simple line of code, we have told React to set up a state unit called budget and to set up a setter. The argument of the useState() call is the initial value. In our case, we have set it to be 4000 Euros.

看看我们做了什么。首先,我们从React中导入了useState钩子。useState钩子可能是其中最简单的一个,它返回两个值,一个变量(可以是我们想要的任何东西,一个数组或一个对象)和一个为这个状态变量设置值的函数。尽管您可以使用任何合法的JavaScript名称,但最好使用变量的名称(在本例中是budget)和相同的名称,并加上set:setBudget。这就是它的全部!通过这行简单的代码,我们告诉React设置一个名为budget的状态单元并设置一个setter。useState()调用的参数是初始值。在我们的案例中,我们将其设置为4000欧元。

Now we are free to use this state variable across the page. Note that we placed the useState call inside the App functional component, if you try to place it elsewhere, it will not work: hooks tap into the life cycle of components from the inside of the bodies of the functions defining the components themselves.

现在我们可以在整个页面上自由地使用这个状态变量。注意,我们把useState调用放在了App功能组件内部,如果你试图把它放在其他地方,它将无法工作:钩子从定义组件本身的函数体内部进入组件的生命周期。

Moving down to the bottom of the component, we can see that we added a simple textbox. We set it to only display numeric values with HTML, and we added an onchange handler.

移动到组件的底部,我们可以看到我们添加了一个简单的文本框。我们将其设置为仅用HTML显示数字值,并添加了一个onchange处理程序。

This is a good moment to mention that React uses the so-callled SyntheticEvent, a wrapper around the browser’s native events that enables React to achieve cross-browser compatibility. The documentation is very straight forward, and you can find it on the React website: https://reactjs.org/docs/events.html. Once you have remembered a couple of differences (the events are using camelCase, rather than lowercase, and you must pass them a function in JSX), you will be writing event handlers in no time.

现在是提及React使用所谓的SyntheticEvent的好时机,SyntheticEvent是浏览器原生事件的包装器,它使React能够实现跨浏览器兼容性。文档非常直接,你可以在React网站上找到它:https://reactjs.org/docs/events.html。一旦您记住了两个不同之处(事件使用的是camelCase,而不是小写,并且您必须在JSX中向它们传递一个函数),您将很快编写事件处理程序。

Back to our App.js file. We added an onChange event to the textbox and set it to be handled by a function, we called it onChangeHandler.

回到我们的App.js文件。我们在文本框中添加了一个onChange事件,并将其设置为由一个函数处理,我们称之为onChangeHandler。

This onChangeHandler could hardly get any simpler: it just takes the current value of the textbox (target.value, just like the original DOM events; remember, it’s just a wrapper) and sets our budget state to this value using our useState call defined jsut above the function. Finally, we added a div element just below the Header component that uses this budget value and displays it. That’s it, we added a state variable to our app, the root component. We can set it and get it, and we are displaying it on the page!

这个onChangeHandler再简单不过了:它只获取文本框(target)的当前值。值,就像原来的DOM事件一样;记住,它只是一个包装器),并使用函数上方定义的useState调用将预算状态设置为这个值。最后,我们在Header组件下面添加了一个div元素,该元素使用这个预算值并显示它。就是这样,我们在应用中添加了一个状态变量,根组件。我们可以设置它并获取它,然后在页面上显示它!

Now let us try another thing. We have the user entering their budget and displaying it on the page. Wouldn’t it be nice if we could somehow differentiate between cars that fit said budget and those that do not? To get this to work, we will need to set our small data sample that is currently hardcoded to be a state variable itself, and then we could just filter it and display only those within our price range.

现在让我们试试另一件事。我们让用户输入他们的预算并显示在页面上。如果我们能以某种方式区分符合上述预算的汽车和不符合预算的汽车,那不是很好吗?为了实现这一点,我们需要将当前硬编码的小数据样本设置为状态变量本身,然后我们可以过滤它并仅显示在价格范围内的数据样本。

I will not go through the code for this, but you can find it in this book’s GitHub repository. The procedure would be to set a new state variable that holds an array of cars satisfying the condition that their price is less than or equal to our budget(hint:JavaScript filtering arrays) and then just add setDisplayedCars to the budget event handler.

我不会详细介绍它的代码,但您可以在本书的GitHub存储库中找到它。该过程将设置一个新的状态变量,该变量保存一个汽车数组,该数组满足其价格小于或等于预算的条件(提示:JavaScript过滤数组),然后将setDisplayedCars添加到预算事件处理程序中。

At this point, I must encourage you to dive into the excellent React.js documentation and learn more about the useState hook and its big brother, the useReducer hook. This is a hook that might be thought of as a generalization of the useState hook and that is best suited when you have to deal with numerous pieces of state that are interconnected, so managing them with many simple useState hooks could end up being tedious and difficult to maintain.

在这一点上,我必须鼓励你深入研究优秀的React.js文档,学习更多关于useState钩子和它的大哥useReducer钩子的知识。这是一个可以被认为是useState钩子的泛化的钩子,当您必须处理许多相互连接的状态片段时,它是最适合的,因此使用许多简单的useState钩子来管理它们可能会变得乏味且难以维护。

Now I am going to delet the contents of our App.js file, leaving only the empty Tailwind-styled canvas and the header.

现在我要删除App.js文件的内容,只留下空的tailwind风格的画布和标题。

import Header from "./components/Header";

function App() {
    return (
        <div className="App max-w-3xl mx-auto h-full">
            <Header/>
        </div>
    );
}

export default App;

You have seen how the useState hook enables you to add a stateful variable in a very simple and staightforward way and how to manipulate the state through regular envents.

您已经看到了useState钩子如何使您能够以一种非常简单和直接的方式添加有状态变量,以及如何通过常规事件操作状态。

Now it is time to see how we can get our data from our efficient FastAPI backend into our beautiful React.js frontend. We will get to know another hook: useEffect.

现在是时候看看如何从高效的FastAPI后端获取数据到漂亮的React.js前端。我们将了解另一个钩子:useEffect。


http://www.niftyadmin.cn/n/5465392.html

相关文章

OpenHarmony实战:Hilog组件在交互时应用指南

一、OpenHarmony hilog 组件工具概述 hilog 是 OpenHarmony 日志系统&#xff0c;提供给系统框架、服务、以及应用打印日志&#xff0c;记录用户操作、系统运行状态等。适用于 OpenHarmony 应用、硬件开发及测试人员,是每个开发人员的必备、入门工具。 hilog 日志查看命令行工…

搭建Spark单机版环境

在搭建Spark单机版环境的实战中&#xff0c;首先确保已经安装并配置好了JDK。然后&#xff0c;从群共享下载Spark安装包&#xff0c;并将其上传至目标主机的/opt目录。接着&#xff0c;解压Spark安装包至/usr/local目录&#xff0c;并配置Spark的环境变量&#xff0c;以确保系统…

日记本(源码+文档)

日记本&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明功能项目截图客户端首页日记列表 书写日记个人中心设置密码锁拨打客服热线修改信息退出登录登录页输入密码锁注册页 后端管理登录页首页管理员列表管理用户管理日记列表管理日记数据 文件包含…

Flutter 关键字

import ‘package:xxxx.dart’; //源于pub.dev (完美的相对引入) import ‘xxxx.dart’; //自定义文件(库)(参考的相对引入(填写import命令码所在文件的上级文件夹下的文件(库)相对路径))(受到import命令码所在文件的参考路径的影响) import&#xff1a;import不具有传递性(类似…

【前端面试3+1】08 css选择器、在前端页面展示后端传来的图片数组、请求方法的常见类型、【搜索插入位置】

一、css选择器有哪些&#xff1f; 1.元素选择器&#xff1a; 通过元素名称选择元素。 示例&#xff1a;p 选择所有段落元素。 2.类选择器&#xff1a; 通过类名选择元素。 示例&#xff1a;.btn 选择所有类名为 btn 的元素。 3.ID选择器&#xff1a; 通过id属性选择元素。 示例…

华盛顿大学撰文反驳微软,我们无法删除大模型关于哈利波特的记忆

在人工智能的发展过程中&#xff0c;一个引人入胜的议题是机器学习模型是否能够被训练以忘记其曾经学到的信息。近期&#xff0c;Ronen Eldan和Mark Russinovich在其研究“谁才是哈利波特&#xff1f;”[1]中提出了一种创新技术&#xff0c;声称能够从LLMs中“抹去”特定数据集…

ChernoCPP

视频链接&#xff1a;https://www.youtube.com/playlist?listPLlrATfBNZ98dudnM48yfGUldqGD0S4FFb 参考文章链接&#xff1a;TheChernoCppTutorial_the cherno-CSDN博客 欢迎来到C C可以直接控制硬件&#xff0c;C的代码被编译器编译输出为目标平台的机器码&#xff0c;机器…

GPIO的基础知识

GPIO的基础知识 STM32H7 的GPIO基本配置不使用的引脚设置为模拟模式IO补偿单元关闭补偿单元开启补偿单元 注入电流大小和特性GPIO 的8种模式四种输入模式两种输出模式推挽输出开漏输出 复用推挽和开漏 GPIO拉灌电流负载能力GPIO兼容CMOS和TTL 首先对于GPIO我们需要注意以下几点…