《React.js手把手教程:从初学者到实战高手》
第一部分:React.js基础
章节 3:React.js基础
在这一章中,我们将进一步了解 React.js 的基础知识。我们会从最基本的 React 组件开始,逐步引导你进入 React.js 的世界。
React组件的基本结构
在 React.js 中,有两种定义组件的方式,分别是函数式组件(function component)和类组件(class component)。React 官方目前似乎更推崇函数式组件,因此在本书中,我们将更多地使用函数式组件。但在本小节中,我也会向你简单介绍类组件的写法。
用你喜欢的编辑器(例如:VS Code)再次打开我们之前创建的 my-react-app 项目,在 src
目录下创建一个新的文件夹 components
,我们将用这个文件夹存放我们自己创建的组件。
然后,我们将在 src/components
文件夹中创建一个名为 HelloWorld.js
的文件,并将以下代码添加到其中:
import React from 'react';function HelloWorld() {return (<h1>Hello, World!</h1>);
}export default HelloWorld;
在上面的代码中,我们定义了一个名为 HelloWorld
的函数式组件,它的返回值是我们在前面学过的JSX,这个JSX的内容内容比较好理解,它是一个HTML中的 h1
标签。对于函数式组件,它的返回值就是渲染在页面上的内容。
接下来,我们再来看看类组件的写法。其实我们在前面的章节中已经初步认识过类组件。
在 src/components
文件夹中创建一个名为 Greeting.js
的文件,并将以下代码加入进去:
import React, { Component } from 'react';class Greeting extends Component {render() {return (<h1 style={{ color: 'red' }}>Hello from the Greeting class component!</h1>);}
}export default Greeting;
在上面的代码中,我们定义了一个名为 Greeting
的类组件。对于类组件,它应该继承自 React 的 Component 类,并需要有一个 render
方法。render
方法的返回值就是这个组件渲染在网页上的内容。
使用组件
现在我们已经创建了一个简单的函数式组件 HelloWorld
和一个类组件 Greeting
,接下来我们将学习如何使用它们。
打开项目中的 src/App.js
,用以下代码替换掉原来的代码:
import React from 'react';
import './App.css';
import HelloWorld from './components/HelloWorld';
import Greeting from './components/Greeting';function App() {return (<div className="App"><HelloWorld /><Greeting /></div>);
}export default App;
让我来对这些代码做一些解释,使你能了解这些代码是什么意思。
先来看看以下这两行代码:
import HelloWorld from './components/HelloWorld';
import Greeting from './components/Greeting';
你在接触本书之前应该就已经对 import
有所了解了。以上两行代码将我们刚才创建的两个组件导入了当前文件中。
再来看 App
组件中是如何使用 HelloWorld
和 Greeting
这两个组件的。
<HelloWorld /><Greeting />
以上这两行代码分别将 HelloWorld
和 Greeting
这两个组件加入了 App
组件中。
HelloWorld
和 Greeting
是组件的名字。对于组件,在JSX中用 <>
将其名字包起来就能使用了。
由于 HelloWorld
是函数式组件,因此当 App
组件渲染在页面上时, HelloWorld
组件的返回值将会呈现在 <HelloWorld />
所在的位置。
由于 Greeting
是类组件,因此当 App
组件渲染在页面上时, Greeting
组件的 render
函数的返回值将会呈现在 <Greeting />
所在的位置。
接下来让我们看看代码运行后的效果。用以下命令启动项目(如果你的项目正在运行中,则不用再次执行此命令,当修改文件后,网页会自动应用最新的代码):
npm start
然后你将在网页中看到如下结果:
向组件传递数据(Props)
在 React 中,通过 props 参数,我们可以向组件传递数据。这让我们可以根据不同的数据渲染出不同的内容,使组件具有的复用的意义。
我们继续在 src/components
文件夹中创建一个名为 WelcomeMessage.js
的文件,并将以下代码添加到其中:
import React from 'react';function WelcomeMessage(props) {return (<div><h2>Welcome, {props.name}!</h2><p>{props.message}</p></div>);
}export default WelcomeMessage;
在上面的代码中,我们定义了一个名为 WelcomeMessage
的函数式组件,它接收一个名为 props
的参数。通过 props
,我们可以获取传递给组件的数据,然后在组件中使用。
接下来,我们需要在 App.js
文件中使用刚刚创建的 WelcomeMessage
组件,并向其传递数据:
import React from 'react';
import './App.css';
import HelloWorld from './components/HelloWorld';
import Greeting from './components/Greeting';
import WelcomeMessage from './components/WelcomeMessage';function App() {return (<div className="App"><HelloWorld /><Greeting /><WelcomeMessage name="Alice" message="Welcome to our website!" /><WelcomeMessage name="Bob" message="Hello there!" /></div>);
}export default App;
注意以下两行代码:
<WelcomeMessage name="Alice" message="Welcome to our website!" /><WelcomeMessage name="Bob" message="Hello there!" />
这两行代码加入了两个 WelcomeMessage
组件,但传递的参数不同。
在 JSX 中,用属性(props)给组件传递参数。写法与HTML元素类似。
上面的代码给第一个WelcomeMessage
组件传递了两个参数,分别是 name
和 message
,它们的值分别是 "Alice"
和 "Welcome to our website!"
。
给第二个WelcomeMessage
组件也传递了两个参数 name
和 message
,它们的值分别是 "Bob"
和 "Hello there!"
。
再回过头来看看 WelcomeMessage
组件是如何使用这些参数的。注意 WelcomeMessage
组件中的以下两行代码:
<h2>Welcome, {props.name}!</h2><p>{props.message}</p>
在组件中,参数 props
对应的就是传递过来的参数,它是一个 Object
。
由于我们在 App.js
中给 WelcomeMessage
组件传递了 name
和 message
两个参数,那么组件 WelcomeMessage
所接收到的 props
参数中就会有 name
和 message
这两个数据。
在 JSX 中,{}
内包含的是 JavaScript表达式。因此当这个组件渲染时, {props.name}
和 {props.message}
将分别对传递过来的 name
和 message
参数的值所替换。
这时,你的浏览器中应该显示的是下面这个样子(由于项目正在运行中,因此当修改代码后,浏览器会自动应用最新的代码):
以上是函数式组件接收参数的示例。我们再来看看在类组件中是如何接收参数的。
我们现在将 WelcomeMessage
组件修改为类组件。将 src/components/WelcomeMessage.js
中的代码修改为以下这个样子:
import React from 'react';class WelcomeMessage extends React.Component {render () {return (<div><h2>Welcome, {this.props.name}!</h2><p>{this.props.message}</p></div>);}
}export default WelcomeMessage;
在类组件中,传递过来的参数存在于 this.props
中。因此这里可以用 this.props.name
和 this.props.message
获得传递过来的 name
和 message
参数的值。
对于这个类组件,JSX 中的每个 <WelcomeMessage />
都是一个 WelcomeMessage
类的实例。如果你要为这个类组件补齐构造函数,它应该是类似以下这样子的:
constructor (props) {super(props);}
保存代码后,你将会发现网页中显示的与之前是一样的。也就是说,这个类组件与之前的函数式组件所渲染的内容是一样的。