首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

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。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ORLHRXs8I4nJl9Vv8DtKX2Tw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券