React脚手架(2)组件的结构和JSX

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/FlowGuanEr/article/details/89446938

组件的创建

前端的文件目录树,除了特定的配置文件之外,其他都可以按照自己的项目需求创建,但是要层次结构分明,一般情况下,我们按照组件功能或者路由来生成项目的目录树(示例在src目录下新建一个components文件夹,然后在其中新建组件)。

  • 组件的文件

React中的组件都是以JS文件的形式呈现的。

新建HeaderNav组件,那就新建一个header-nav.js

  • 组件的代码

React中组件的具体代码形式是一个class类,比如:

class HeaderNav {
	// code 
}
export default HeaderNav

这个类和普通的JS的类没有什么区别,那么如何区分组件类和普通的类。

React封装了一个Component类,在其中封装了React提供的组件的基本操作,声明一个普通的类,让其继承于Component类,那么这个类就会被当做一个组件去使用,也可以调用React提供给组件的所有属性和方法。

import React from 'react'
class HeaderNav extends React.Component {
	render() {
		 return <h1>我是一小段测试代码</h1>;
	}
}
export default HeaderNav

组件的调用

一般情况下,框架中调用组件至少两种方式,父组件调用子组件和路由调用组件。我们先说父组件调用子组件(路由单独介绍)。

  • 在父组件中导入子组件(比如我们要在App中调用HeaderNav,那就在App.js中导入header-nav.js):
// App.js
import HeaderNav from './components/header-nav.js'
  • 在父组件的结构中调用被导入的子组件(示例将App中的默认结构删除了)
// App.js
...
class App extends Component {
	render() {
		return (
			<div className="App">
      			<HeaderNav />
      		</div>
      	);
    }
}
...

组件的结构

上面的组件创建和调用中,组件的HTML结构声明在JS代码中,被一个r ender函数返回。这种结构声明的方式就是React的核心之一,JSX语法。render函数是ReactDOM对象的一个方法,React使用它解析JSX语法并渲染在DOM上。

ReactDOM.render()函数

一、 根组件

React中只有一个根节点(在一个已有项目中引入react除外),这个根节点在"public/index.html"中,如果要将某个结构渲染在浏览器上,必须使用ReactDOM.render函数。

当然这个配置是在安装项目时默认就有的,在"public/index.html"中有一个id为"root"的div,在"src/index.js"中,导入了App组件,并使用ReactDOM.render()函数将其渲染到了"root"中:

// public/index.html
...
<div id="root"></div>
...
// src/index.js
...
import App from './App'
...
...
ReactDOM.render(<App />, document.getElementById('root'));
...

二、子组件

每一个组建类中都要有一个render函数,这个render函数返回一个JSX语法声明的元素,就是当前组件的结构代码。

JSX语法

React中,由JSX语法声明结构代码(HTML),之后用React语法调用。

一、JSX

JSX允许在JS代码中直接编写HTML结构代码。

  1. 单一结构
// header-nav.js
import React from 'react'

// 使用JSX语法,用一个变量承接一个JSX元素
const el = <h1>取次花丛懒回顾,半缘修道半缘君。</h1>;

class HeaderNav extends React.Component {
	render() {
		return el; // 直接调用el变量
	}
}
export default HeaderNav
  1. 嵌套结构
// header-nav.js
...
// 如果元素结构较为复杂,为了避免不必要的bug,我们要将JSX语法写在一对小括号中
const el = (
	<div>
		<p>曾经沧海难为水</p>
		<p>除去巫山不是云</p>
		<p>取次花丛懒回顾</p>
		<p>半缘修道半缘君</p>	
	</div>
);
...
  1. JSX中写表达式
    框架的结构中结合表达式使用是一种常规操作,JSX中的表达式用{}包裹:
// header-nav.js
...
const arr = ['取次花丛懒回顾','半缘修道半缘君'];
const el = (
	<div>
		<p>{arr[0]}</p>
		<p>{arr[1]}</p>
	</div>
);
...
  • {}中的表达式可以是三目运算、逻辑运算等。
  1. 如果我们要利用JSX封装一个常用的模块(弹框),这个模块的结构不变,但是每次调用它时,结构中显示的内容不定,那么我们可以使用函数封装这个公共模块(这种封装建议函数名大写)。
// header-nav.js
import React from 'react'

function Message() {
	return (<div>
		<p>取次花丛懒回顾</p>
		<p>半缘修道半缘君</p>
	</div>);
}
class HeaderNav extends React.Component {
	render() {
		return (
			<div>
				<Message />
			</div>
		);
	}
}
export default HeaderNav

在上面的示例中,Message就是一个被封装的模块。Message被封装后可能会被重复调用,每次调用时,内部展示的内容可能都是不定的。所以我们可以在调用Message时向其传参。

  1. 调用封装好的模块并向其传参
// header-nav.js
import React from 'react'

// 封装Message模块,并接收参数
function Message(props) {
	return (<div>
		<p>{props.arr[0]}</p>
		<p>{props.arr[1]}</p>
	</div>);
}
class HeaderNav extends React.Component {
	render() {
		return (
			<div>
				<Message  arr={['身无彩凤双飞翼','心有灵犀一点通']} />
				<Message  arr={['天长地久有时尽','此恨绵绵无绝期']} />
			</div>
		);
	}
}
export default HeaderNav

Message模块被复用,并且再被复用时接收了动态的数据。

注:

  • 如果还有其他参数,那就和arr一样,在调用该组件时以属性的形式传参即可;
  • props对象接收模块被调用时的参数列表;
  • 公共模块的封装一般比较复杂,可以将其疯转在单独的JS文件中,再在需要调用的组件内导入使用;
  • 如果某些公共模块内部的组件逻辑较为复杂,建议直接将其封装成组件,不推荐函数封装这种方法;

二、React.createElement()函数

JSX声明元素本质上是React对象的createElement()函数提供的语法糖。

// JSX:
const el = <h1></h1>;

// 本质:
React.createElement('h1');

所以如果要在某个JS文件中编写JSX语法,必须要提前引入React。

/* 
React.createElement(elName,props,...children);
elName: 要新建的模块的名称;
props: 属性列表;(具体请参照文档)
children: 子元素列表;
*/

参考文档:
官方文档中对于项目目录树的说明

猜你喜欢

转载自blog.csdn.net/FlowGuanEr/article/details/89446938