react创建自定义组件
The author selected Creative Commons to receive a donation as part of the Write for DOnations program.
作者选择了创用CC来接受捐赠,这是Write for DOnations计划的一部分。
In this tutorial, you’ll learn to create custom components in React. Components are independent pieces of functionality that you can reuse in your application, and are the building blocks of all React applications. Often, they can be simple JavaScript functions and classes, but you use them as if they were customized HTML elements. Buttons, menus, and any other front-end page content can all be created as components. Components can also contain state information and display markdown.
在本教程中,您将学习在React中创建自定义组件 。 组件是可以在应用程序中重用的独立功能,并且是所有React应用程序的构建块。 通常,它们可以是简单的JavaScript函数和类 ,但是您可以像使用自定义HTML元素一样使用它们。 按钮,菜单和任何其他前端页面内容都可以创建为组件。 组件还可以包含状态信息和显示减价。
After learning how to create components in React, you’ll be able to split complex applications into small pieces that are easier to build and maintain.
在学习了如何在React中创建组件之后,您将能够将复杂的应用程序拆分为更易于构建和维护的小块。
In this tutorial, you’ll create a list of emojis that will display their names on click. The emojis will be built using a custom component and will be called from inside another custom component. By the end of this tutorial, you’ll have made custom components using both JavaScript classes and JavaScript functions, and you’ll understand how to separate existing code into reusable pieces and how to store the components in a readable file structure.
在本教程中,您将创建一个表情符号列表,将在单击时显示其名称。 表情符号将使用自定义组件构建,并将从另一个自定义组件内部调用。 在本教程结束时,您将使用JavaScript类和JavaScript函数制作自定义组件,并且您将了解如何将现有代码分成可重用的片段,以及如何将组件存储在可读的文件结构中。
You will need a development environment running Node.js; this tutorial was tested on Node.js version 10.20.1 and npm version 6.14.4. To install this on macOS or Ubuntu 18.04, follow the steps in How to Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.
您将需要一个运行Node.js的开发环境; 本教程已在Node.js 10.20.1版和npm 6.14.4版上进行了测试。 要将其安装在macOS或Ubuntu 18.04上,请遵循如何在macOS上安装Node.js并创建本地开发环境中的步骤,或如何在Ubuntu 18.04上安装Node.js的 使用PPA安装部分中的步骤 。
You will need to be able to create apps with Create React App. You can find instructions for installing an application with Create React App at How To Set Up a React Project with Create React App.
您将需要能够使用Create React App创建应用程序 。 您可以在如何使用创建React App 设置React项目中找到有关使用Create React App安装应用程序的说明。
You will be using JSX syntax, which you can learn about in our How To Create Elements with JSX tutorial.
您将使用JSX语法,您可以在我们的“ 如何使用JSX创建元素”教程中了解该语法。
You will also need a basic knowledge of JavaScript, which you can find in How To Code in JavaScript, along with a basic knowledge of HTML and CSS. A good resource for HTML and CSS is the Mozilla Developer Network.
您还将需要JavaScript的基本知识,以及HTML和CSS的基本知识,这些知识可以在JavaScript的How To Code中找到。 Mozilla开发人员网络是HTML和CSS的良好资源。
In this step, you’ll create a base for your project using Create React App. You will also modify the default project to create your base project by mapping over a list of emojis and adding a small amount of styling.
在这一步中,您将使用创建React App为您的项目创建基础。 您还将通过映射表情符号列表并添加少量样式来修改默认项目以创建基础项目。
First, create a new project. Open a terminal, then run the following command:
首先,创建一个新项目。 打开一个终端,然后运行以下命令:
npx create-react-app tutorial-03-component
npx create-react-app 教程-03-组件
Once this is finished, change into the project directory:
完成此操作后,进入项目目录:
cd tutorial-03-component
cd 教程03-组件
Open the App.js
code in a text editor:
在文本编辑器中打开App.js
代码:
Next, take out the template code created by Create React App, then replace the contents with new React code that displays a list of emojis:
接下来,取出由Create React App创建的模板代码,然后将内容替换为显示表情符号列表的新React代码:
import React from 'react';
import './App.css';
const displayEmojiName = event => alert(event.target.id);
const emojis = [
{
emoji: '',
name: "test grinning face"
},
{
emoji: '',
name: "party popper"
},
{
emoji: '',
name: "woman dancing"
}
];
function App() {
const greeting = "greeting";
const displayAction = false;
return(
Hello, World
{displayAction && I am writing JSX
}
{
emojis.map(emoji => (
-
))
}
)
}
export default App;
This code uses JSX syntax to map()
over the emojis
array and list them as list items. It also attaches
onClick
events to display emoji data in the browser. To explore the code in more detail, check out How to Create React Elements with JSX, which contains a detailed explanation of the JSX.
此代码使用JSX语法在emojis
数组上进行map()
并将其列为列表项。 它还附加
onClick
事件,以在浏览器中显示表情符号数据。 要更详细地探索代码,请查看如何使用JSX创建React Elements ,其中包含有关JSX的详细说明。
Save and close the file. You can now delete the logo.svg
file, since it was part of the template and you are not referencing it anymore:
保存并关闭文件。 现在,您可以删除logo.svg
文件,因为它是模板的一部分,并且不再引用它:
Now, update the styling. Open src/App.css
:
现在,更新样式。 打开src/App.css
:
Replace the contents with the following CSS to center the elements and adjust the font:
用以下CSS替换内容以使元素居中并调整字体:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
button {
font-size: 2em;
border: 0;
padding: 0;
background: none;
cursor: pointer;
}
ul {
display: flex;
padding: 0;
}
li {
margin: 0 20px;
list-style: none;
padding: 0;
}
This uses flex
to center the main and list elements. It also removes default button styles and
styles so the emojis line up in a row. More details can be found at How to Create React Elements with JSX.
这使用flex
将主要和list元素居中。 它还会删除默认的按钮样式和
样式,以便表情符号连续排成一行。 可以在如何使用JSX创建React Elements中找到更多详细信息。
Save and exit the file.
保存并退出文件。
Open another terminal window in the root of your project. Start the project with the following command:
在项目的根目录中打开另一个终端窗口。 使用以下命令启动项目:
After the command runs, you’ll see the project running in your web browser at http://localhost:3000
.
命令运行后,您将在Web浏览器中的http://localhost:3000
看到正在运行的项目。
Leave this running the entire time you work on your project. Every time you save the project, the browser will auto-refresh and show the most up-to-date code.
在您处理项目的整个过程中,都要一直运行。 每次保存项目时,浏览器都会自动刷新并显示最新代码。
You will see your project page with Hello, World and the three emojis that you listed in your App.js
file:
您将在项目页面上看到Hello,World以及在App.js
文件中列出的三个表情符号:
Now that you’ve set up your code, you can now start putting together components in React.
设置好代码后,您就可以开始在React中组合组件了。
Now that you have your project running, you can start making your custom component. In this step, you’ll create an independent React component by extending the base React Component
class. You’ll create a new class, add methods, and use the render function to show data.
现在,您的项目正在运行,您可以开始制作自定义组件。 在这一步中,您将通过扩展基本React Component
类来创建一个独立的React组件。 您将创建一个新类,添加方法,并使用render函数显示数据。
React components are self-contained elements that you can reuse throughout a page. By making small, focused pieces of code, you can move and reuse pieces as your application grows. The key here is that they are self-contained and focused, allowing you to separate out code into logical pieces. In fact, you have already been working with logically separated components: The App.js
file is a functional component, one that you will see more of in Step 3.
React组件是独立的元素,可以在整个页面中重复使用。 通过编写小的,集中的代码段,您可以随着应用程序的增长而移动和重用这些代码段。 这里的关键是它们是独立的且具有重点,使您可以将代码分成逻辑部分。 实际上,您已经在使用逻辑上分开的组件: App.js
文件是一个功能组件,您将在步骤3中看到更多内容。
There are two types of custom component: class-based and functional. The first component you are going to make is a class-based component. You will make a new component called Instructions
that explains the instructions for the emoji viewer.
自定义组件有两种类型: 基于类和函数 。 您要制作的第一个组件是基于类的组件。 您将创建一个名为“ Instructions
的新组件,该组件Instructions
了表情符号查看器的指令。
Note: Class-based components used to be the most popular way of creating React components. But with the introduction of React Hooks, many developers and libraries are shifting to using functional components.
注意:基于类的组件曾经是创建React组件的最流行的方式。 但是随着React Hooks的引入,许多开发人员和库都在转向使用功能组件。
Though functional components are now the norm, you will often find class components in legacy code. You don’t need to use them, but you do need to know how to recognize them. They also give a clear introduction to many future concepts, such as state management. In this tutorial, you’ll learn to make both class and functional components.
尽管现在功能组件已成为规范,但您经常会在旧版代码中找到类组件。 您不需要使用它们,但是您确实需要知道如何识别它们。 他们还清晰地介绍了许多未来的概念,例如状态管理。 在本教程中,您将学习制作类和功能组件。
To start, create a new file. By convention, component files are capitalized:
首先,创建一个新文件。 按照惯例,组件文件大写:
Then open the file in your text editor:
然后在文本编辑器中打开文件:
First, import React
and the Component
class and export Instructions
with the following lines:
首先,导入React
和Component
类,并使用以下行导出Instructions
:
import React, { Component } from 'react';
export default class Instructions extends Component {}
Importing React
will convert the JSX. Component
is a base class that you’ll extend to create your component. To extend that, you created a class that has the name of your component (Instructions
) and extended the base Component
with the export
line. You’re also exporting this class as the default with export default
keywords at the start of the class declaration.
导入React
将转换JSX。 Component
是您将扩展以创建Component
的基类。 为此,您创建了一个具有组件名称的类( Instructions
),并使用export
行扩展了基本Component
。 您还将在类声明的开头使用export default
关键字将此类export default
类。
The class name should be capitalized and should match the name of the file. This is important when using debugging tools, which will display the name of the component. If the name matches the file structure, it will be easier to locate the relevant component.
类名应大写并与文件名匹配。 当使用调试工具时,这很重要,它将显示组件的名称。 如果名称与文件结构匹配,则将更容易找到相关组件。
The base Component
class has several methods you can use in your custom class. The most important method, and the only one you’ll use in this tutorial, is the render()
method. The render()
method returns the JSX code that you want to display in the browser.
基础Component
类具有几种可以在自定义类中使用的方法 。 最重要的方法(也是本教程中唯一要使用的方法render()
是render()
方法。 render()
方法返回要在浏览器中显示的JSX代码。
To start, add a little explanation of the app in a tag:
首先,在标记中添加一些应用说明:
import React, { Component } from 'react';
export class Instructions extends Component {
render() {
return(
Click on an emoji to view the emoji short name.
)
}
}
Save and close the file. At this point, there’s still no change to your browser. That’s because you haven’t used the new component yet. To use the component, you’ll have to add it into another component that connects to the root component. In this project,
is the root component in index.js
. To make it appear in your application, you’ll need to add to the
component.
保存并关闭文件。 此时,您的浏览器仍然没有更改。 这是因为您尚未使用新组件。 要使用该组件,您必须将其添加到连接到根组件的另一个组件中。 在此项目中,
是index.js
的根组件。 要使其出现在您的应用程序中,您需要添加到
组件。
Open src/App.js
in a text editor:
在文本编辑器中打开src/App.js
:
First, you’ll need to import the component:
首先,您需要导入组件:
import React from 'react';
import Instructions from './Instructions';
import './App.css';
...
export default App;
Since it’s the default import, you could import to any name you wanted. It’s best to keep the names consistent for readability—the import should match the component name, which should match the file name—but the only firm rule is that the component must start with a capital letter. That’s how React knows it’s a React component.
由于这是默认导入,因此您可以导入所需的任何名称。 最好保持名称的一致性,以提高可读性-导入应与组件名称匹配,而组件名称应与文件名称匹配-但唯一的固定规则是组件必须以大写字母开头。 这就是React知道它是React组件的方式 。
Now that you’ve imported the component, add it to the rest of your code as if it were a custom HTML element:
现在,您已经导入了该组件,将其添加到其余代码中,就好像它是自定义HTML元素一样:
import React from 'react';
import Instructions from './Instructions.js'
...
function App() {
const greeting = "greeting";
const displayAction = false;
return(
Hello, World
{displayAction && I am writing JSX
}
{
emojis.map(emoji => (
-
))
}
)
}
export default App;
In this code, you wrapped the component with angle brackets. Since this component doesn’t have any children, it can be self closing by ending with />
.
在此代码中,您用尖括号包裹了组件。 由于此组件没有任何子代,因此可以通过以/>
结尾来自动关闭。
Save the file. When you do, the page will refresh and you’ll see the new component.
保存文件。 完成后,页面将刷新,您将看到新组件。
Now that you have some text, you can add an image. Download an emoji image from wikimedia and save it in the src
directory as emoji.svg
with the following command:
现在您已经有了一些文本,您可以添加图像。 从下载表情符号图像维基并将其保存在src
目录emoji.svg
用下面的命令:
curl
makes the request to the URL, and the -o
flag allows you to save the file as src/emoji.svg
.
curl
向URL发出请求,并且-o
标志允许您将文件另存为src/emoji.svg
。
Next, open your component file:
接下来,打开您的组件文件:
Import the emoji and add it to your custom component with a dynamic link:
导入表情符号并通过动态链接将其添加到您的自定义组件中:
import React, { Component } from 'react';
import emoji from './emoji.svg'
export default class Instructions extends Component {
render() {
return(
<>
Click on an emoji to view the emoji short name.
>
)
}
}
Notice that you need to include the file extension .svg
when importing. When you import, you are importing a dynamic path that is created by webpack when the code compiles. For more information, refer to How To Set Up a React Project with Create React App.
请注意,导入时需要包括文件扩展名.svg
。 导入时,将导入由webpack在代码编译时创建的动态路径。 有关更多信息,请参阅如何使用Create React App设置React项目 。
You also need to wrap the
and tags with empty tags to ensure that you are returning a single element.
您还需要用空标签包装
和标签,以确保返回单个元素。
Save the file. When you reload, the image will be very large compared to the rest of the content:
保存文件。 重新加载时,与其余内容相比,图像将非常大:
To make the image smaller, you’ll need to add some CSS and a className
to your custom component.
为了缩小图像,您需要在自定义组件中添加一些CSS和className
。
First, in Instructions.js
, change the empty tags to a div and give it a className
of instructions
:
首先,在Instructions.js
,将空标签更改为div并为其指定一个className
的instructions
:
import React, { Component } from 'react';
import emoji from './emoji.svg'
export default class Instructions extends Component {
render() {
return(
Click on an emoji to view the emoji short name.
)
}
}
Save and close the file. Next open App.css
:
保存并关闭文件。 接下来打开App.css
:
Create rules for the .instructions
class selector:
为.instructions
类选择器创建规则:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
...
.instructions {
display: flex;
flex-direction: column;
align-items: center;
}
When you add a display
of flex
styling, you make the img
and the p
centered with flexbox. You changed the direction so that everything lines up vertically with flex-direction: column;
. The line align-items: center;
will center the elements on the screen.
添加flex
样式display
时,将img
和p
为flexbox居中 。 您更改了方向,以使所有内容与flex-direction: column;
垂直flex-direction: column;
。 线align-items: center;
将元素在屏幕上居中。
Now that your elements are lined up, you need to change the image size. Give the img
inside the div
a width
and height
of 100px
.
现在您的元素已对齐,您需要更改图像大小。 将div
内的img
的width
和height
为100px
。
.container {
display: flex;
flex-direction: column;
align-items: center;
}
...
.instructions {
display: flex;
flex-direction: column;
align-items: center;
}
.instructions img {
width: 100px;
height: 100px;
}
Save and close the file. The browser will reload and you’ll see the image is much smaller:
保存并关闭文件。 浏览器将重新加载,您会看到图像小得多:
At this point, you’ve created an independent and reusable custom component. To see how it’s reusable, add a second instance to App.js
.
至此,您已经创建了一个独立且可重用的自定义组件。 要查看其可重用性,请向App.js
添加第二个实例。
Open App.js
:
打开App.js
:
In App.js
, add a second instance of the component:
在App.js
,添加组件的第二个实例:
import React from 'react';
import Instructions from './Instructions.js'
...
function App() {
const greeting = "greeting";
const displayAction = false;
return(
Hello, World
{displayAction && I am writing JSX
}
{
emojis.map(emoji => (
-
))
}
)
}
export default App;
Save the file. When the browser reloads, you’ll see the component twice.
保存文件。 当浏览器重新加载时,您将看到该组件两次。
In this case, you wouldn’t want two instances of Instructions
, but you can see that the component can be efficiently reused. When you create custom buttons or tables, you will likely use them multiple times on one page, making them perfect for custom components.
在这种情况下,您将不需要两个Instructions
实例,但是您可以看到该组件可以有效地重用。 创建自定义按钮或表格时,您可能会在一页上多次使用它们,从而使其非常适合自定义组件。
For now, you can delete the extra image tag. In your text editor, delete the second
and save the file:
目前,您可以删除多余的图片标签。 在文本编辑器中,删除第二个
并保存文件:
import React from 'react';
import Instructions from './Instructions.js'
...
function App() {
const greeting = "greeting";
const displayAction = false;
return(
Hello, World
{displayAction && I am writing JSX
}
{
emojis.map(emoji => (
-
))
}
)
}
export default App;
Now you have a reusable, independent component that you can add to a parent component multiple times. The structure you have now works for a small number of components, but there is a slight problem. All of the files are mixed together. The image for
is in the same directory as the assets for
. You also are mixing the CSS code for
with the CSS for
.
现在,您有了一个可重用的独立组件,可以将其多次添加到父组件中。 您现在拥有的结构可用于少量组件,但是存在一个小问题。 所有文件混合在一起。
的图像与
的资产位于同一目录中。 您还将混合
CSS代码和
CSS。
In the next step, you’ll create a file structure that will give each component independence by grouping their functionality, styles, and dependencies together, giving you the ability to move them around as you need.
在下一步中,您将创建一个文件结构,该结构将每个组件的功能,样式和依赖项组合在一起,从而使它们相互独立,从而使您能够根据需要移动它们。
In this step, you’ll create a file structure to organize your components and their assets, such as images, CSS, and other JavaScript files. You’ll be grouping code by component, not by asset type. In other words, you won’t have a separate directory for CSS, images, and JavaScript. Instead you’ll have a separate directory for each component that will contain the relevant CSS, JavaScript, and images. In both cases, you are separating concerns.
在此步骤中,您将创建一个文件结构来组织您的组件及其资产,例如图像,CSS和其他JavaScript文件。 您将按组件而不是资产类型对代码进行分组。 换句话说,您将没有用于CSS,图像和JavaScript的单独目录。 相反,您将为每个组件具有一个单独的目录,其中将包含相关CSS,JavaScript和图像。 在这两种情况下,您都是分开关注的 。
Since you have an independent component, you need a file structure that groups the relevant code. Currently, everything is in the same directory. List out the items in your src
directory:
由于您具有独立的组件,因此需要一个将相关代码分组的文件结构。 当前,所有内容都在同一目录中。 列出src
目录中的项目:
The output will show that things are getting pretty cluttered:
输出将显示事情变得很混乱:
Output
App.css Instructions.js index.js
App.js emoji.svg serviceWorker.js
App.test.js index.css setupTests.js
You have code for the
component (App.css
, App.js
, and App.test.js
) sitting alongside your root component (index.css
and index.js
) and your custom component Instructions.js
.
您有
组件( App.css
, App.js
和App.test.js
)的App.js
, App.test.js
与根组件( index.css
和index.js
)和自定义组件Instructions.js
index.css
。
React is intentionally agnostic about file structure. It does not recommend a particular structure, and the project can work with a variety of different file hierarchies. But we recommend to add some order to avoid overloading your root directory with components, CSS files, and images that will be difficult to navigate. Also, explicit naming can make it easier to see which pieces of your project are related. For example, an image file named Logo.svg
may not clearly be part of a component called Header.js
.
React 故意与文件结构无关 。 它不建议使用特定的结构,并且该项目可以使用各种不同的文件层次结构。 但是我们建议添加一些命令,以避免在根目录中加载难以导航的组件,CSS文件和图像。 同样,显式命名可以使您更轻松地查看项目的哪些部分。 例如,名为Logo.svg
的图像文件可能显然不是名为Header.js
的组件的一部分。
One of the simplest structures is to create a components
directory with a separate directory for each component. This will allow you to group your components separately from your configuration code, such as serviceWorker
, while grouping the assets with the components.
最简单的结构之一是创建一个components
目录,每个组件都有一个单独的目录。 这将使您可以将组件与配置代码(例如serviceWorker
分开分组,同时将资产与组件进行分组。
Components
目录 (Creating a Components
Directory)To start, create a directory called components
:
首先,创建一个名为components
的目录:
Next, move the following components and code into the directory: App.css
, App.js
, App.test.js
, Instructions.js
, and emoji.svg
:
接下来,将以下组件和代码移动到目录中: App.css
, App.js
, App.test.js
, Instructions.js
和emoji.svg
:
Here, you are using a wildcard (*
) to select all files that start with App.
.
在这里,您使用通配符( *
)选择所有以App.
开头的文件App.
。
After you move the code, you’ll see an error in your terminal running npm start
.
移动代码后,您将在运行npm start
的终端中看到错误。
Output
Failed to compile.
./src/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'
Remember, all of the code is importing using relative paths. If you change the path for some files, you’ll need to update the code.
请记住,所有代码都是使用相对路径导入的。 如果您更改某些文件的路径,则需要更新代码。
To do that, open index.js
.
为此,请打开index.js
。
Then change the path of the App
import to import from the components/
directory.
然后,更改要从components/
目录导入的App
导入的路径。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import * as serviceWorker from './serviceWorker';
...
serviceWorker.unregister();
Save and close the file. Your script will detect the changes and the error will disappear.
保存并关闭文件。 您的脚本将检测到更改,错误将消失。
Now you have components in a separate directory. As your applications become more complex, you may have directories for API services, data stores, and utility functions. Separating component code is the first step, but you still have CSS code for Instructions
mixed in the App.css
file. To create this logical separation, you will first move the components into separate directories.
现在,您将组件放在单独的目录中。 随着应用程序变得越来越复杂,您可能具有用于API服务,数据存储和实用程序功能的目录。 分离组件代码是第一步,但是App.css
文件中仍然混合有用于Instructions
CSS代码。 要创建这种逻辑分离,首先需要将组件移动到单独的目录中。
First, make a directory specifically for the
component:
首先,为
组件创建一个目录:
Then move the related files into the new directory:
然后将相关文件移到新目录中:
When you do you’ll get a similar error to the last section:
当您执行此操作时,将得到与上一节类似的错误:
Output
Failed to compile.
./src/components/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'
In this case, you’ll need to update two things. First, you’ll need to update the path in index.js
.
在这种情况下,您需要更新两件事。 首先,您需要更新index.js
的路径。
Open the index.js
file:
打开index.js
文件:
Then update the import path for App to point to the App
component in the App
directory.
然后更新App的导入路径,以指向App
目录中的App
组件。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';
...
serviceWorker.unregister();
Save and close the file. The application still won’t run. You’ll see an error like this:
保存并关闭文件。 该应用程序仍然无法运行。 您会看到如下错误:
Output
Failed to compile.
./src/components/App/App.js
Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'
Since
is not on the same directory level as the
component, you’ll need to change the import path. Before that, create a directory for Instructions
. Make a directory called Instructions
in the src/components
directory:
由于
与
组件不在同一目录级别,因此您需要更改导入路径。 在此之前,为Instructions
创建一个目录。 在src/components
目录中创建一个名为“ Instructions
”的目录:
Then move Instructions.js
and emoji.svg
into that directory:
然后将Instructions.js
和emoji.svg
移至该目录:
Now that the Instructions
component directory has been created, you can finish updating the file paths to connect your component to your app.
现在,已经创建了Instructions
组件目录,您可以完成更新文件路径以将组件连接到应用程序。
import
路径 (Updating import
Paths)Now that components are in individual directories, you can adjust the import path in App.js
.
现在,组件位于单独的目录中,您可以在App.js
调整导入路径。
Open App.js
:
打开App.js
:
Since the path is relative, you’ll need to move up one directory—src/components
—then into the Instructions
directory for Instructions.js
, but since this is a JavaScript file, you don’t need the final import.
由于路径是相对的,你需要上移一个目录- src/components
-然后到Instructions
的目录Instructions.js
,但由于这是一个JavaScript文件,你并不需要最后导入。
import React from 'react';
import Instructions from '../Instructions/Instructions.js';
import './App.css';
...
export default App;
Save and close the file. Now that your imports are all using the correct path, you’re browser will update and show the application.
保存并关闭文件。 现在您的导入都使用正确的路径,浏览器将更新并显示该应用程序。
Note: You can also call the root file in each directory index.js
. For example, instead of src/components/App/App.js
you could create src/components/App/index.js
. The advantage to this is that your imports are slightly smaller. If the path points to a directory, the import will look for an index.js
file. The import for src/components/App/index.js
in the src/index.js
file would be import ./components/App
. The disadvantage of this approach is that you have a lot of files with the same name, which can make it difficult to read in some text editors. Ultimately, it’s a personal and team decision, but it’s best to be consistent.
注意:您还可以在每个目录index.js
调用根文件。 例如,可以创建src/components/App/index.js
而不是src/components/App/App.js
这样做的好处是您的进口量略小。 如果路径指向目录,则导入将查找index.js
文件。 src/index.js
文件中src/components/App/index.js
的import ./components/App
将是import ./components/App
。 这种方法的缺点是您有很多同名文件,这可能使某些文本编辑器难以阅读。 最终,这是个人和团队的决定,但是最好保持一致。
Now each component has its own directory, but not everything is fully independent. The last step is to extract the CSS for Instructions
to a separate file.
现在,每个组件都有其自己的目录,但并非所有组件都是完全独立的。 最后一步是将Instructions
CSS提取到单独的文件中。
First, create a CSS file in src/components/Instructions
:
首先,在src/components/Instructions
创建一个CSS文件:
Next, open the CSS file in your text editor:
接下来,在文本编辑器中打开CSS文件:
Add in the instructions CSS that you created in an earlier section:
添加在前面部分中创建的说明CSS:
.instructions {
display: flex;
flex-direction: column;
align-items: center;
}
.instructions img {
width: 100px;
height: 100px;
}
Save and close the file. Next, remove the instructions CSS from src/components/App/App.css
.
保存并关闭文件。 接下来,从src/components/App/App.css
删除CSS说明。
Remove the lines about .instructions
. The final file will look like this:
删除有关.instructions
的行。 最终文件如下所示:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
button {
font-size: 2em;
border: 0;
padding: 0;
background: none;
cursor: pointer;
}
ul {
display: flex;
padding: 0;
}
li {
margin: 0 20px;
list-style: none;
padding: 0;
}
Save and close the file. Finally, import the CSS in Instructions.js
:
保存并关闭文件。 最后,将CSS导入Instructions.js
:
Import the CSS using the relative path:
使用相对路径导入CSS:
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'
export default class Instructions extends Component {
render() {
return(
Click on an emoji to view the emoji short name.
)
}
}
Save and close the file. Your browser window will look as it did before, except now all the file assets are grouped in the same directory.
保存并关闭文件。 您的浏览器窗口将与以前一样,但现在所有文件资产都分组在同一目录中。
Now, take a final look at the structure. First, the src/
directory:
现在,最后看一下结构。 首先, src/
目录:
You have the root component index.js
and the related CSS index.css
next to the components/
directory and utility files such as serviceWorker.js
and setupTests.js
:
你有根组件index.js
和相关CSS index.css
旁边components/
目录和实用程序文件等serviceWorker.js
和setupTests.js
:
Output
components serviceWorker.js
index.css setupTests.js
index.js
Next, look inside components
:
接下来,查看内部components
:
You’ll see a directory for each component:
您将看到每个组件的目录:
Output
App Instructions
If you look inside each component, you’ll see the component code, CSS, test, and image files if they exist.
如果查看每个组件内部,将看到组件代码,CSS,测试和图像文件(如果存在)。
Output
App.css App.js App.test.js
Output
Instructions.css Instructions.js emoji.svg
At this point, you’ve created a solid structure for your project. You moved a lot of code around, but now that you have a structure, it will scale easier.
至此,您已经为项目创建了坚实的结构。 您移动了很多代码,但是现在有了结构,它将可以轻松扩展。
This is not the only way to compose your structure. Some file structures can take advantage of code splitting by specifying a directory that will be split into different packages. Other file structures split by route and use a common directory for components that are used across routes.
这不是构成您的结构的唯一方法。 一些文件结构可以通过指定将被拆分为不同软件包的目录来利用代码拆分的优势。 其他文件结构按路由拆分,并为跨路由使用的组件使用公用目录。
For now, stick with a less complex approach. As a need for another structure emerges, it’s always easier to move from simple to complex. Starting with a complex structure before you need it will make refactoring difficult.
就目前而言,坚持使用不太复杂的方法。 随着对另一种结构的需求的出现,从简单结构过渡到复杂结构总是很容易。 在需要之前从复杂的结构开始将使重构变得困难。
Now that you have created and organized a class-based component, in the next step you’ll create a functional component.
现在您已经创建并组织了一个基于类的组件,在下一步中,您将创建一个功能组件。
In this step, you’ll create a functional component. Functional components are the most common component in contemporary React code. These components tend to be shorter, and unlike class-based components, they can use React hooks, a new form of state and event management.
在此步骤中,您将创建一个功能组件。 功能组件是当代React代码中最常见的组件。 这些组件往往更短,并且与基于类的组件不同,它们可以使用React钩子 (一种新的状态和事件管理形式)。
A functional component is a JavaScript function that returns some JSX. It doesn’t need to extend anything and there are no special methods to memorize.
功能组件是返回一些JSXJavaScript函数。 它不需要扩展任何内容,也没有特殊的记忆方法。
To refactor
as a functional component, you need to change the class to a function and remove the render method so that you are left with only the return statement.
要将
重构为功能组件,您需要将类更改为函数并删除render方法,以便只剩下return语句。
To do that, first open Instructions.js
in a text editor.
为此,首先在文本编辑器中打开“ Instructions.js
。
Change the class
declaration to a function
declaration:
将class
声明更改为function
声明:
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'
export default function Instructions() {
render() {
return(
Click on an emoji to view the emoji short name.
)
}
}
Next, remove the import of { Component }
:
接下来,删除{ Component }
的导入:
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'
export default function Instructions() {
render() {
return(
Click on an emoji to view the emoji short name.
)
}
}
Finally, remove the render()
method. At that point, you are only returning JSX.
最后,删除render()
方法。 那时,您只返回JSX。
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'
export default function Instructions() {
return(
Click on an emoji to view the emoji short name.
)
}
Save the file. The browser will refresh and you’ll see your page as it was before.
保存文件。 浏览器将刷新,您将看到以前的页面。
You could also rewrite the function as an arrow function using the implicit return. The main difference is that you lose the function body. You will also need to first assign the function to a variable and then export the variable:
您也可以使用隐式return将函数重写为箭头函数 。 主要区别在于您失去了功能主体。 您还需要先将函数分配给变量,然后导出变量:
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'
const Instructions = () => (
Click on an emoji to view the emoji short name.
)
export default Instructions;
Simple functional components and class-based components are very similar. When you have a simple component that doesn’t store state, it’s best to use a functional component. The real difference between the two is how you store a component’s state and use properties. Class-based components use methods and properties to set state and tend to be a little longer. Functional components use hooks to store state or manage changes and tend to be a little shorter.
简单的功能组件和基于类的组件非常相似。 当您有一个不存储状态的简单组件时,最好使用功能组件。 两者之间的真正区别在于您如何存储组件的状态和使用属性。 基于类的组件使用方法和属性来设置状态,并且往往要更长一些。 功能组件使用挂钩来存储状态或管理更改,并且往往要短一些。
Now you have a small application with independent pieces. You created two major types of components: functional and class. You separated out parts of the components into directories so that you could keep similar pieces of code grouped together. You also imported and reused the components.
现在您有了一个带有独立组件的小型应用程序。 您创建了两种主要类型的组件:功能组件和类。 您将组件的各个部分分离到目录中,以便可以将相似的代码片段分组在一起。 您还导入并重用了组件。
With an understanding of components, you can start to look at your applications as pieces that you can take apart and put back together. Projects become modular and interchangable. The ability to see whole applications as a series of components is an important step in thinking in React. If you would like to look at more React tutorials, take a look at our React Topic page, or return to the How To Code in React.js series page.
了解了组件之后,您可以将应用程序看成是可以分解并重新组合在一起的部分。 项目变得模块化和可互换。 将整个应用程序视为一系列组件的能力是在React中思考的重要一步。 如果您想看更多的React教程,请看一下我们的React Topic页面 ,或者回到React.js系列中的How To Code页面 。
翻译自: https://www.digitalocean.com/community/tutorials/how-to-create-custom-components-in-react
react创建自定义组件