IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React系统学习3(組件三大核心属性之props) -> 正文阅读

[JavaScript知识库]React系统学习3(組件三大核心属性之props)

从一个小需求出发

假设有这样一个需求,需要在页面中输出不同水果的一些信息,例如id编号、名称和价格。

在这里插入图片描述

很显然,上边有三种不同的水果,但是每一种的格式是一模一样的,看起来就是ulli

那么根据之前的学习,可以先定义出类似这样的组件以及相关代码,先实现其中一个:

<body>
	<div id="test"></div>

	<!--核心库-->
	<script type="text/javascript" src="../../js/react.development.js"></script>
	<!--操作dom-->
	<script type="text/javascript" src="../../js/react-dom.development.js"></script>
	<!--用户将jsx转为js-->
	<script type="text/javascript" src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

	<script type="text/babel">
		class Order extends React.Component{
		render() {
			return (
				<ul>
					<li>id:1</li>
					<li>name:苹果</li>  
					<li>price:6.8元</li>
				</ul>
			)
		}
		}

		ReactDOM.render(<Order/>,document.getElementById('test'))
	</script>
</body>

上边已经实现出来了一种水果的信息展示,如果要三个都出来,需要怎么办呢?实现方式不止一种,例如最简单粗暴的就可以直接在组件里写三个ul

但是很显然这样存在一些问题,其中一个问题就是这样的数据是写死的,而实际上这些数据不应该是固定的,例如价格。

另一个问题就是,真的写多个ul的话,明显是不符合组件的思想的,组件本身就是为了复用,如果写成这样子,那就完全体现不出来组件的意义。

那么下边就来解决这两个问题。

数据处理

由于之前学过了state,所以第一时间就能想到把数据从固定变为不固定,可以用state试试,于是组件的定义改成了如下这样:

class Order extends React.Component{
	state = {id:1,name:'苹果',price:6.8}
	render() {
		return (
			<ul>
				<li>id:{this.state.id}</li>
				<li>name:{this.state.name}</li>  
				<li>price:{this.state.price}元</li>
			</ul>
		)
	}
}

看起来,数据好像不是固定的了,因为state里边数据可以通过构造方法等初始化方式获得,还可以通过事件回调进行修改。

但是这里依然只是一个水果,要继续实现三个水果的展示又要怎么办呢?

首先,可能会先把代码写成这样:

<body>
	<div id="test"></div>
	<div id="test1"></div>
	<div id="test2"></div>

	<!--核心库-->
	<script type="text/javascript" src="../../js/react.development.js"></script>
	<!--操作dom-->
	<script type="text/javascript" src="../../js/react-dom.development.js"></script>
	<!--用户将jsx转为js-->
	<script type="text/javascript" src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

	<script type="text/babel">
		class Order extends React.Component{
		state = {id:1,name:'苹果',price:6.8}
		render() {
			return (
				<ul>
					<li>id:{this.state.id}</li>
					<li>name:{this.state.name}</li>  
					<li>price:{this.state.price}元</li>
				</ul>
			)
		}
		}

		ReactDOM.render(<Order/>,document.getElementById('test'))
		ReactDOM.render(<Order/>,document.getElementById('test1'))
		ReactDOM.render(<Order/>,document.getElementById('test2'))
	</script>

</body>

上边代码看起来展示了三种水果,也实现了组件的复用,但是实际上展示效果是这样的:
在这里插入图片描述

这并不是展示了三种水果,而是一个水果展示了三次。

如何解决这个问题呢?这就需要今天的主角props上场了。

props基本用法

propsstate一样是react内置的属性之一,props可以理解为就是组件标签的属性集合,会帮我们收集组件中所有属性。

使用props可以很好的解决上边的问题,修改后的组件定义以及使用的基本代码如下:

class Order extends React.Component{
	render() {
		return (
			<ul>
				<li>id:{this.props.id}</li>
				<li>name:{this.props.name}</li>  
				<li>price:{this.props.price}元</li>
			</ul>
		)
	}
}

ReactDOM.render(<Order id={1} name='苹果' price={6.8}/>,document.getElementById('test'))
ReactDOM.render(<Order id={2} name='香蕉' price={3.7}/>,document.getElementById('test1'))
ReactDOM.render(<Order id={3} name='梨子' price={4.5}/>,document.getElementById('test2'))

进行上边这样的修改后,刷新页面就可以看到结果是最开头想要的效果了,如下:
在这里插入图片描述

对象解构

虽然效果是实现了,但是上边代码却显得比较繁琐,示例中仅仅展示了三个属性,而真实开发中经常会十几甚至几十的属性,那么像上边这样的代码就会显得极其难看。

上边代码是可以优化的,其中一个就是对象解构,例如组件定义中使用属性时如果使用解构写法,就可以改成下边这样:

render() {
	const {id,name,price} =this.props;
	return (
		<ul>
			<li>id:{id}</li>
			<li>name:{name}</li>  
			<li>price:{price}元</li>
		</ul>
	)
}

解构相当于就是把一个对象的属性一个个拿出来,然后赋值给新的变量,这样之后使用的时候直接使用对应的变量就可以了,而不需要每次都从原对象中拿,代码看起来就会简洁很多。

三点展开运算符传值

除了组件中使用数据可以用解构来优化代码外,组件使用时的代码也是可以优化的。

上边的代码中,三个属性是分别传递的,当属性特别多的时候就特别难写,也特别难看。

同时,实际开发的时候一般这种数据也是从后端返回,基本也都是对象的方式,而不是直接一个一个属性的返回。

因此在使用组件并传数据的时候,上边的代码可以进一步优化为下边这样:

//模拟数据
let fruit={id:1,name:'苹果',price:6.8}
let fruit1={id:2,name:'香蕉',price:3.7}
let fruit2={id:3,name:'梨子',price:4.5}

ReactDOM.render(<Order {...fruit}/>,document.getElementById('test'))
ReactDOM.render(<Order {...fruit1}/>,document.getElementById('test1'))
ReactDOM.render(<Order {...fruit2}/>,document.getElementById('test2'))

当然了,真正开发时要怎么写,还要看具体的需求,如果本身就只需要其中几个属性,那么自然也可以直接传值。

数据约束及默认值

上边代码实现了一开始的需求,最做了一定的优化,但是还是不够完善,因为实际开发的时候,经常需要对数据进行约束,例如数据的类型限定,例如是否必传,例如没有数据的时候是否需要默认值等等。

针对上边的代码,如果要加上这些限制,可以改成这样:

class Order extends React.Component{
	render() {
		const {id,name,price} =this.props;
		return (
			<ul>
				<li>id:{id}</li>
				<li>name:{name}</li>  
				<li>price:{price}元</li>
			</ul>
		)
	}
}

Order.propTypes={
	id:PropTypes.number.isRequired,
	name:PropTypes.string
}

Order.defaultProps={
	price:0
}

let fruit={id:1,name:'苹果',price:6.8}
let fruit1={id:2,name:'香蕉',price:3.7}
let fruit2={id:3,name:'梨子'}

ReactDOM.render(<Order {...fruit}/>,document.getElementById('test'))
ReactDOM.render(<Order {...fruit1}/>,document.getElementById('test1'))
ReactDOM.render(<Order {...fruit2}/>,document.getElementById('test2'))

有了上边新增的Order.propTypesOrder.defaultProps后,就可以实现一些数据的限制以及默认值。

例如这里限制了id必须是数字类型,并且必传;限制了name必须是字符串类型,但是可以不传;没有对price进行数据类型以及是否必传的限制,但是通过```Order.defaultProps`给它了默认值。

有了这些限制后,如果对应的数据不符合要求,页面也会显示,只是在控制台会有警告输出。

另外需要注意的是,这里的数字类型使用number,字符串使用string,如果类型是函数则需要使用func,因为function是关键字,所以需要替换。

还需要注意的是,PropTypesReact内置的类,在React15.5之前可以直接使用React.PropTypes,而之后的版本则需要额外引入一个依赖,例如:

<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>

约束和默认值的优化

上边的代码还可以进一步优化,因为从定义可以看出来propTypesdefaultProps都是属于类的,但是却将他们定义在了类外边,就显得不那么好。

所以这两个定义是可以放到类里边的,使他们能够更清楚的显示和类的关系,修改后如下:

class Order extends React.Component{
	static propTypes={
		id:PropTypes.number.isRequired,
		name:PropTypes.string
	}

	static defaultProps={
		price:0
	}


	render() {
		const {id,name,price} =this.props;
		return (
			<ul>
				<li>id:{id}</li>
				<li>name:{name}</li>  
				<li>price:{price}元</li>
			</ul>
		)
	}
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:32:12  更:2022-04-18 17:35:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:11:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码