react微信小程序ui库
by Kelly Burke
凯莉·伯克(Kelly Burke)
如何在React Web应用程序中使用Material-UI显示应用程序内消息 (How to show in-app messages using Material-UI in a React web app)
In some situations, your web app needs to show an informational message to tell users whether an event was successful or not. For example, a “Success” message after a user clicks a button and successfully completes some action.
在某些情况下,您的Web应用程序需要显示一条参考消息,以告诉用户事件是否成功。 例如,用户单击按钮并成功完成某些操作后,显示“成功”消息。
In this tutorial, I’ll show you how to create a simple component for informational, in-app messages with React and Material-UI. We’ll call it a Notifier
component.
在本教程中,我将向您展示如何使用React和Material-UI为信息性应用内消息创建一个简单组件。 我们将其称为Notifier
组件。
Here are the main sections of this tutorial:
这是本教程的主要部分:
- Getting started 入门
- Notifier component 通告程序组件
- Import Notifier component to Index page 将通知程序组件导入索引页面
- Testing 测试中
If you find this article useful, consider starring our Github repo and checking out our book where we cover this and many other topics in detail.
如果您觉得这篇文章很有用,请考虑为我们的Github回购加注星标,并查看我们的书 ,其中详细介绍了此主题和许多其他主题。
入门 (Getting started)
For this tutorial, I’ve created a simple web app for you to follow. We’ll use code located in the tutorials/4-start folder of our builderbook repo.
在本教程中,我创建了一个简单的Web应用程序供您遵循。 我们将使用位于builderbook repo的tutorials / 4-start文件夹中的代码 。
If you don’t have time to run the app locally, I deployed this example app here.
如果您没有时间在本地运行该应用程序,请在此处部署此示例应用程序。
To run the app locally:
要在本地运行该应用程序:
- Clone the builderbook repo to your local machine with: 使用以下命令将builderbook存储库克隆到本地计算机:
git clone git@github.com:builderbook/builderbook.git
Inside the
4-start
folder, runyarn
ornpm install
to install all packages listed inpackage.json
.在
4-start
文件夹中,运行yarn
或npm install
来安装package.json
列出的所有软件包。Run
yarn dev
to start the app.运行
yarn dev
启动应用程序。
索引页 (Index page)
On your browser, go to http://localhost:3000. This is our Index
page, which has the /
route. Next.js provides automatic routing for pages located in a /pages
folder. The name of each page file becomes that page’s route.
在浏览器上,转到http:// localhost:3000 。 这是我们的Index
页面,其中包含/
路线。 Next.js为/pages
文件夹中的/pages
提供自动路由。 每个页面文件的名称将成为该页面的路由。
Our Index
page is a simple page component that renders a form, an input, and a button (more explanation below).
我们的Index
页面是一个简单的页面组件,它呈现一个表单,一个输入和一个按钮(下面有更多说明)。
Here’s the code for our Index
page at pages/index.js
:
这是我们在pages/index.js
Index
页面的代码:
A few notes:
一些注意事项:
We could have defined this page as a stateless functional component, since it has no state, lifecycle hooks, or refs (read more about when to use stateless functional components versus React ES6 classes). You’ll see this Eslint warning:
Component should be written as a pure function
. However, the finalIndex
page that we write in this tutorial will have ref. Hence, we wrote this initialIndex
page as a child of ES6 class using extends.我们可以将该页面定义为无状态功能组件,因为它没有状态,生命周期挂钩或引用( 阅读更多有关何时使用无状态功能组件和React ES6类的信息)。 您会看到以下Eslint警告:
Component should be written as a pure function
。 但是,我们在本教程中编写的最终Index
页面将具有参考。 因此,我们写了这首 使用extends作为ES6类的子级的Index
页。We imported Head from Next.js in order to customize the
<He
ad> element of the page. Inside
<Head>, we added a
page<t
itle> and<meta> description for proper indexing by search engine bots (good for SEO).
The text inside <title> displays on your browser tab:我们从Next.js导入Head ,以自定义页面的
<He
ad>元素。 我nside
<HEAD>,我们一dded a
页面<t
通过搜索引擎机器人(好FO书名>和<META>描述了正确的索引r SEO).
<title>中的文本显示在浏览器选项卡上:
We used Material-UI’s TextField and Button components, which render into
<inp
ut>; and &l
t;button> HTML elements, respectively.我们使用了Material-UI的TextField和Button组件,它们呈现为
<inp
ut>; and &l
; and &l
t; button> HTML元素。We wrapped our page with a
withLayout
higher-order component. Our app uses Next.js, andwithLayout
ensures that server-side rendering works properly for Material-UI inside our React-Next app.withLayout
also adds ourHeader
component (located atcomponents/Header.js
) to each page thatwithLayout
wraps. Server-side rendering is not necessary for Material-UI or React, but it is a main feature of Next.js. We discussed server-side vs. client-side rendering in React apps in another tutorial.我们用
withLayout
高阶组件包装页面。 我们的应用程序使用Next.js,withLayout
确保在React-Next应用程序中服务器端渲染对于Material-UI正常工作。withLayout
还将我们的Header
组件(位于components/Header.js
)添加到withLayout
环绕的每个页面上。 对于Material-UI或React,服务器端渲染不是必需的,但这是Next.js的主要功能。 在另一篇教程中,我们讨论了React应用程序中的服务器端渲染与客户端渲染 。
We are done describing our initial Index
page. Now let’s discuss the Notifier
component that we will later import into the Index
page to show informational messages to our web app users.
我们已经完成了对初始Index
页面的描述。 现在让我们讨论Notifier
组件,稍后将其导入到“ Index
页面以向我们的Web应用程序用户显示参考消息。
通告程序组件 (Notifier component)
Let’s start by defining the Notifier
component. We define Notifier
as a React.Component
instead of a stateless function, because Notifier
will have state, one lifecycle method, and a few event handling functions.
让我们从定义Notifier
组件开始。 我们将Notifier
定义为React.Component
而不是无状态函数,因为Notifier
将具有状态,一个生命周期方法和一些事件处理函数。
For our informational messages, we will use Material-UI’s Snackbar. Check out examples of using Snackbar on the official Material-UI site.
对于我们的参考消息,我们将使用Material-UI的Snackbar 。 在官方Material-UI网站上查看使用Snackbar的示例 。
Here’s a high-level outline of our Notifier
component:
这是我们Notifier
组件的高级概述:
Create a Notifier.js
file inside the /components
folder of 4-start
. Add the above high-level outline to this file. Below, we will replace the numbered comments with code.
在4-start
的/components
文件夹内创建一个Notifier.js
文件。 将上面的高级大纲添加到此文件。 在下面,我们将用代码替换编号的注释。
1. We will use the open
and message
props of Material-UI’s Snackbar for the state of our Notifier
. Check the full list of props for Snackbar.
1.我们将使用Material-UI的Snackbar的open
和message
属性作为Notifier
的状态。 查看Snackbar 道具的完整列表 。
Initially, our Notifier
should be in a closed state with an empty string as a message. We define the Notifier
's initial state as:
最初,我们的Notifier
应处于关闭状态,并以空字符串作为消息。 我们将Notifier
的初始状态定义为:
2. Now let’s write a function that updates the state of the Notifier component. The function will change the value of the open
prop to true
and set the value of the message
prop to a non-empty string. Let’s call this function openSnackbar()
.
2.现在,让我们编写一个更新通告程序组件状态的函数。 该函数会将open
属性的值更改为true
,并将message
属性的值设置为非空字符串。 我们将此函数openSnackbar()
。
Before we can execute openSnackbar()
, our Notifier
component needs to be mounted in the DOM. Thus, we put the openSnackbar()
function into a componentDidMount
lifecycle method that executes right after the Notifier
component mounts in the DOM.
在执行openSnackbar()
,需要将我们的Notifier
组件安装在DOM中。 因此,我们将openSnackbar()
函数放入componentDidMount
生命周期方法中,该方法在Notifier
组件在DOM中装入后立即执行。
In order to access the openSnackbar()
function anywhere in our app, we have to set its value to another function that is available outside of the Notifier
component. Hence, we write let openSnackbarFn
above class Notifier extends React.Component
.
为了在应用程序中的任何位置访问openSnackbar()
函数,我们必须将其值设置为Notifier
组件之外可用的另一个函数。 因此,我们在class Notifier extends React.Component
之上编写let openSnackbarFn
class Notifier extends React.Component
。
Putting these pieces together:
将这些片段放在一起:
Now let’s define the openSnackbar()
function. This function will update the open
and message
properties of our Notifier
’s state. Once the state is updated, the Notifier
component will get re-rendered to show a message (open:true
displays the Snackbar, and message:message
sets the message).
现在让我们定义openSnackbar()
函数。 此函数将更新Notifier
状态的open
和message
属性。 更新状态后,将重新渲染Notifier
组件以显示消息( open:true
显示小吃栏,而message:message
设置消息)。
Inside this.setState
, we could have written message
as message:message
. Instead, we used ES6 shorthand syntax (enforced by Eslint) to make the code more concise.
在this.setState
内部,我们可以将message
编写为message:message
。 相反,我们使用ES6 速记语法 (由Eslint强制执行)使代码更简洁。
3. When a user clicks outside of the Snackbar area, the Snackbar should close. The Snackbar prop onClose
is responsible for this behavior. Let’s write a function called handleSnackbarClose()
that sets open
to false
and message
to an empty string.
3.当用户单击“小吃栏”区域之外时,“小吃栏”应关闭。 Snackbar属性onClose
负责此行为。 让我们编写一个名为handleSnackbarClose()
的函数,该函数将open
设置为false
并将message
设置为空字符串。
4. Finally, let’s write code for our Notifier
component to render the Snackbar component with all necessary props.
4.最后,让我们为Notifier
组件编写代码,以使用所有必要的道具渲染Snackbar组件。
In addition to the message
, onClose
, and open
props described above, we’ll add the following props to our Snackbar component:
除了上述message
, onClose
和open
道具外,我们还将以下道具添加到Snackbar组件中:
anchorOrigin
: specifies the Snackbar locationanchorOrigin
:指定anchorOrigin
的位置autoHideDuration
: specifies the Snackbar duration in millisecondsautoHideDuration
:指定Snackbar持续时间(以毫秒为单位)SnackbarContentProps
: binds the Snackbar to an element inside the DOM that containsmessage
; in our case, the element has the idsnackbar-message-id
, and the Snackbar will display text from this element.SnackbarContentProps
:将SnackbarContentProps
绑定到DOM中包含message
的元素; 在我们的例子中,元素的ID为snackbar-message-id
,而Snackbar将显示该元素的文本。
Here is the render()
method of our Notifier
component:
这是我们的Notifier
组件的render()
方法:
In the <sp
an> element, we could have written message={this.state.me
ssage}, but instead we wrote dangerouslySetInnerHTML={{ __html: this.state.mess
age }} . This allows us to add HTML code to the Snackbar’s m
essage prop. For instance, you may want to show a hyperlink to users. Read more about using dangerouslySetInnerHTML in React.
在<sp
an>元素中,我们可以itten message={this.state.me
},但是我们wrote dangerouslySetInnerHTML={{ __html: this.state.mess
age}}。 这使我们可以将HTML代码添加到小吃店bar's m
留言道具。 例如,您可能想显示指向用户的超链接。 有关在React中危险地使用SetInnerHTML的更多信息。
After putting the code from steps 1–4 together, here’s our final Notifier
component:
将步骤1-4中的代码放在一起后,这是我们最终的Notifier
组件:
Important note: notice how we exported our openSnackbar()
function in addition to Notifier
component. We will import both openSnackbar()
and Notifier
into our Index
page.
重要说明:请注意,除了Notifier
组件之外,我们openSnackbar()
如何导出openSnackbar()
函数。 我们将导入这两个 openSnackbar()
并Notifier
到我们的Index
页面。
将通知程序组件导入索引页面 (Import Notifier component to Index page)
Let’s go back to our Index
page, where we will import our Notifier
component and openSnackbar()
function.
让我们回到Index
页面,我们将在其中导入我们的Notifier
组件和openSnackbar()
函数。
Without triggering the openSnackbar()
function, our Notifier
component will always stay in its initial closed state with an empty string as a message. We need to execute openSnackbar()
after a user submits the form by clicking the button on our Index
page. Let’s define a showNotifier()
function that does exactly that.
在不触发openSnackbar()
函数的情况下,我们的Notifier
组件将始终保持其初始关闭状态,并带有一条空字符串作为消息。 用户单击“ Index
页面上的按钮提交表单后,我们需要执行openSnackbar()
。 让我们定义一个可以showNotifier()
这一点的showNotifier()
函数。
showNotifier函数 (showNotifier Function)
We will call showNotifier()
inside the <fo
rm> element. We’ll make showNoti
fier() execute when a user enters a number on the form and clicks the “Submit” button.
我们将在<fo
rm>元素内调用showNotifier()
。 当用户在表单上输入数字并单击“提交”按钮时, make showNoti
()执行。
Here’s the current <fo
rm> on our
Index page:
这是n our
索引页面的当前<fo
rm>:
Let’s make two modifications:
让我们进行两个修改:
1. To call showNotifier()
when the form is submitted, we use JavaScript’s onsubmit Event:
1.在提交表单时调用showNotifier()
,我们使用JavaScript的onsubmit事件 :
2. A user will enter a number inside TextField
. In order for our showNotifier()
function to access the value of TextField
, we add React’s ref attribute to TextField
.
2.用户将在TextField
输入一个数字。 为了让showNotifier()
函数访问TextField
的值,我们将React的ref属性添加到TextField
。
There are two ways to get the value of TextField
: with this.state
and with ref
. We chose ref
, since this.state
is more concise. Here’s an explanation of writing with this.state
, and here’s more info about using ref
in React.
有两种方法可以获取TextField
的值: this.state
和ref
。 我们选择ref
,因为this.state
更简洁。 这是使用this.state
编写的解释 ,这是有关在React中使用ref
的更多信息 。
Now let’s define the showNotifier()
function. Here’s the high-level outline for showNotifier()
:
现在让我们定义showNotifier()
函数。 这是showNotifier()
的高级概述:
Below, we’ll write code for each of the three comments above.
下面,我们将为上面的三个注释编写代码。
We define
answer
as:我们将
answer
定义为:
This line of code says that IF answerInput
exists (meaning the <inp
ut> element is added to the DOM), THEN
answer equals the value of answe
rInput, which is accessed with answerInput
.value.
这行代码说,如果answerInput
存在(意味着<inp
UT>元素被添加到DOM), THEN
答案等于VAL ue of answe
rInput,其访问with answerInput
。价值。
IF answerInput
does not exist, THEN the entire condition in parentheses is false and answer
equals null
.
如果answerInput
不存在,则括号中的整个条件为false, answer
等于null
。
2. If a user does not enter an answer on our form but clicks the “Submit” button, we will show this message: Empty field. Enter a number.
2.如果用户未在表单上输入答案,而是单击“提交”按钮,我们将显示以下消息: Empty field. Enter a number.
Empty field. Enter a number.
3. If a user enters 4 and clicks the “Submit” button, then our openSnackbar()
function will run and show this message: Correct answer!
. Otherwise, it will show Incorrect answer.
3.如果用户输入4并单击“提交”按钮,则我们的openSnackbar()
函数将运行并显示以下消息: Correct answer!
。 否则,它将显示Incorrect answer.
We use parseInt(answer, 10)
to parse answer
, which is a string, and return an integer. The parameter 10
specifies that the integer is in decimal format.
我们使用parseInt(answer, 10)
解析answer
,它是一个字符串,并返回一个整数。 参数10
指定整数为十进制格式。
Let’s put together the code from steps 1–3 above for our showNotifier
function. We’ll place the code right under the line class Index extends React.Component
:
让我们将上述步骤1-3中的代码放到showNotifier
函数中。 我们将代码放置在class Index extends React.Component
的行class Index extends React.Component
:
You’ll notice that we added a line event.preventDefault();
. This will prevent our <fo
rm> element from its default behavior of sending form data to a server.
您会注意到我们添加了一行event.preventDefault();
。 这将防止我们的<fo
rm>元素出现其默认行为或将表单数据发送到服务器。
Now we have all the code for our final Index
page:
现在,我们拥有最终Index
页面的所有代码:
测试中 (Testing)
Let’s test that our Notifier
works as expected. Run the app locally with yarn dev
and navigate to http://localhost:3000. If you aren’t running the app, go to the one I deployed: https://notifier.builderbook.org.
让我们测试一下Notifier
按预期工作。 使用yarn dev
在本地运行应用程序,然后导航到http:// localhost:3000 。 如果您没有运行该应用程序,请转到我部署的应用程序: https : //notifier.builderbook.org 。
First, click “Submit” without adding anything in the text field.
首先,单击“提交”,而不在文本字段中添加任何内容。
Next, add the number 4 and click “Submit”.
接下来,添加数字4,然后单击“提交”。
Now add any other number and click “Submit”.
现在添加其他任何数字,然后单击“提交”。
Remember that we wrote code to close the Snackbar when a user clicks away from it (we wrote a handleSnackbarClose()
function and passed it to the onClose
prop of the Snackbar). After seeing the Snackbar, click anywhere besides the Snackbar itself on your screen. The Snackbar should close immediately.
请记住,我们编写了在用户单击时关闭Snackbar的代码(我们编写了handleSnackbarClose()
函数并将其传递给Snackbar的onClose
道具)。 看到快餐栏后,单击屏幕上除快餐栏本身以外的任何地方。 小吃店应立即关闭。
A nice feature of Material-UI is mobile optimization. We don’t have to write extra code for our informational message to look good on mobile devices. See for yourself by going to Chrome’s DevTools and changing the view from desktop to mobile. Our message appears across the top of the screen:
Material-UI的一个不错的功能是移动优化。 我们不必为信息性消息编写额外的代码即可在移动设备上看起来不错。 转到Chrome的DevTools,然后将视图从台式机更改为移动版,即可亲自查看。 我们的消息出现在屏幕顶部:
Woohoo! You’ve successfully added an informational, in-app message to a React web app! Your final code should match the code in the tutorials/4-end folder of our builderbook repo.
hoo! 您已成功向React Web应用程序添加了参考性应用内消息! 您的最终代码应与我们的builderbook repo的tutorials / 4-end文件夹中的代码匹配。
自定义通知程序组件 (Customize Notifier component)
Now that you have a working Notifier
component, let’s see how we can modify the UX by changing props of Material-UI’s SnackBar component. Here’s the full list of props you can use.
现在您有了一个正常的Notifier
组件,让我们看看如何通过更改Material-UI的SnackBar组件的道具来修改UX。 这是您可以使用的道具的完整列表 。
First, let’s change the duration of the Snackbar. Insider your Notifier
component, find the autoHideDuration
prop. Change its value from 3000
to 1000
and compare. You’ll see that at 1000
, the Snackbar closes more quickly.
首先,让我们更改Snackbar的持续时间。 在您的Notifier
组件内部,找到autoHideDuration
道具。 将其值从3000
更改为1000
并进行比较。 您会看到在1000
,小吃栏关闭得更快。
Second, let’s change the position of the Snackbar. Find the anchorOrigin
prop and change its values from top
and right
to bottom
and left
, respectively. Check where the Snackbar appears now:
其次,让我们更改Snackbar的位置。 找到anchorOrigin
道具,并将其值分别从top
和right
更改为bottom
和left
。 检查小吃栏现在出现的位置:
Finally, let’s make the Snackbar message
include a hyperlink. Recall that we added dangerouslySetInnerHTML={{ __html: this.state.message }}
to our message
prop in the Snackbar so that we can write HTML inside of it.
最后,让Snackbar message
包含超链接。 回想一下,我们在Snackbar的message
prop中添加了dangerouslySetInnerHTML={{ __html: this.state.message }}
,以便我们可以在其中编写HTML。
Change the code for our Correct answer!
and Incorrect answer.
messages like this:
更改我们Correct answer!
的代码Correct answer!
和Incorrect answer.
像这样的消息:
Now users will see the messages below. Notice the dark blue hyperlinks for text inside the <
;a> tags.
现在,用户将看到以下消息。 注意<
; a>标记内的文本的深蓝色超链接。
If you’re learning how to build web apps with JavaScript, check out our Github repo and our book, where we cover this and many other topics in detail.
如果您正在学习如何使用JavaScript构建Web应用程序,请查阅我们的Github存储库和我们的书 ,在其中我们将详细介绍该主题以及许多其他主题。
To get email updates about our tutorials, subscribe here.
要获取有关我们教程的电子邮件更新,请在此处订阅。
react微信小程序ui库