React框架-浅谈组件

文章目录

  • 前言
  • 一、类组件
  • 二、无状态组件(函数式组件)
  • 三、无状态组件与类组件的区别
      • 1、类组件
        • state的特点
      • 2、无状态组件(函数式组件)
        • Props
  • 四、表单
        • 1、受控表单:表单的输入和输出由state声明式变量来控制
        • 2、非受控表单:表单的输入和输出与state没有任何关系
        • 3、多个表单取值方法的复用


前言

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。


一、类组件

import React from "react"
import {Child1} from "@/components"

export default class TestState extends React.Component{
	//构造器函数,当前组件被实例化时,会调用该方法
	constructor(props){
		super(props)
		//super必须是构造函数的第一行
		this.state = {
			msg: "hello",
			foo: "1",
			count:0
		}
	}
	
	//自定义方法
	changeMsg(){
		this.setState({
			msg:"hello 2020",
			foo:"100"
		},()=>{
			console.log("更新完成")
		})
//		this.setState({foo:"100"})
	}
	
	add(){
//		第一种写法
//		this.setState({count:this.state.count+1})

//		第二种写法
//		this.setState(function(state,props){
//			return {
//				count:state.count+1
//			}
//		})
		this.setState((state,props)=>({count:state.count+1}))
	}
	
	sub(){
//		this.setState({count:this.state.count-1})
		
//		this.setState(function(state,props){
//			return{
//				count:state.count-1
//			}
//		})

		this.setState((state,props)=>({count:state.count-1}))
	}
	//唯一的不能少的生命周期,否则报错
	render(){
		//在return之前,你可以做任何的运算
		let { msg,count,foo } = this.state
		return (
			<div>
				<h1>测试State</h1>
				<h1 onClick={this.changeMsg.bind(this)}>{msg}</h1>
				<Child1 msg={msg}/>
				<h1>{foo}</h1>
				<hr/>
				<h1>{count}</h1>
				<button onClick={this.add.bind(this)}></button>
				<button onClick={this.sub.bind(this)}></button>
			</div>
		)
	}
}


二、无状态组件(函数式组件)

import React from "react"

//Props
//这是父子组件之间通信的唯一纽带
//props是只读的,不建议直接修改

export default function TestProps(props){
	return(
		<div>
			<h1 onClick= {props.click}>测试Props</h1>
			{ props.msg }
		</div>
	)
}

三、无状态组件与类组件的区别

1、类组件

有state,有this,有生命周期等特性 和无状态组件(函数式组件)相比,性能相对较差

state的特点

1、单向绑定,当state数据发生变化时,视图自动更新(反过来是不行的),视图变化state不改变
2、单向数据流,数据只能向下传递,向子组件传递 3、不能直接修改state中的声明式变量,要使用this.setState()来修改状态
4、this.setState()是异步的,但在定时器中时,又是同步的
5、多个this.setState()发生时,react会自动把它们合并成一个this.setState()

2、无状态组件(函数式组件)

没有state的React组件,也没有生命周期等特性,也没有this 优势:渲染性能高,速度快

Props

这是父子组件之间通信的唯一纽带
props是只读的,不建议直接修改

四、表单

1、受控表单:表单的输入和输出由state声明式变量来控制

//在受控表单中,value/checked 和 onChange是一起使用的,缺一不可。
<input 
	type="text" 
	value={user} 
	onChange={this.change.bind(this,"user")}
/>

checkbox和radio的特殊情况,使用checked用于表单受控

//radio
<div>
	{/*name属性的作用,把一系列互不相关的radio表单变成一组*/}
	{/*value用于给每一个radio一个值,在e.target.value中可以取到它*/}
	{/*checked用于表单受控*/}
	<span>选择性别:</span>
	<input 
		type="radio" 
		name="gender"
		value="1"
		checked={gender==1} 
		onChange={this.change.bind(this,"gender")}
	/>
	<label></label>
	<input 
		type="radio" 
		name="gender"
		value="2"
		checked={gender==2} 
		onChange={this.change.bind(this,"gender")}
	/>
	<label></label>
</div>
//checkbox
<div>
	<input type="checkbox" checked={agree} onChange={this.change.bind(this,"agree")}/>
	<label>是否同意该注册协议</label>
</div>

当checkbox和radio不分组时,需要用e.target.checked来取值,是布尔类型
当checkbox和radio分组时,需要用e.target.value来取值,是字符串类型

2、非受控表单:表单的输入和输出与state没有任何关系

尽量不要使用非受控表单,除了文件上传类的表单

<input type="text" defaultValue={dVal} onInput={this.inputHandle.bind(this)}/>
<input id="pass" type="text"/>
<input ref="pass" type="text"/>
<input type="file"/>
<button onClick={this.submit.bind(this)}>提交</button>

3、多个表单取值方法的复用

对于处理多个受控表单时,需要定义很多onChange,这样比较麻烦,可以这样解决:

1.将onChange事件设置为一个
2.在input表单上面设置不同的name属性(必须设置跟state中定义的变量一样)
3.在事件处理函数中通过事件源对象,根据name属性来修改state的数据

//	userChange(e){
//		//console.log("e",e.target.value)
//		//手动取表单的值,手动更新到state中去
//		this.setState({user:e.target.value})
//	}
//	passChange(e){
//		this.setState({pass:e.target.value})
//	}
//	descChange(e){
//		this.setState({desc:e.target.value})
//	}

//以上方法的复用
	change(key,e){
		//当checkbox和radio不分组时,需要用e.target.checked来取值,是布尔类型
		//当checkbox和radio分组时,需要用e.target.value来取值,是字符串类型
		console.log(e.target.checked,e.target.value)
		if(key=="agree"){
			this.setState({[key]:e.target.checked})
		}else{
			this.setState({[key]:e.target.value})
		}
	}
render(){
		let {user,pass,desc,gender,agree,gradeArr,grade} = this.state
		return(
			<div>
				<h1>测试表单绑定</h1>
				
				{/*受控表单*/}
				<div>
					<span>用户名:</span>
					<input 
						type="text" 
						value={user} 
						onChange={this.change.bind(this,"user")}
					/>
				</div>
				<div>
					<span>密   码:</span>
					<input 
						type="password" 
						value={pass} 
						onChange={this.change.bind(this,"pass")}
					/>
				</div>
				<div>
					<span>个人简介:</span>
					<textarea 
						value={desc} 
						cols="30" 
						rows="3" 
						onChange={this.change.bind(this,"desc")}
					>
					</textarea>
				</div>
				<div>
					{/*name属性的作用,把一系列互不相关的radio表单变成一组*/}
					{/*value用于给每一个radio一个值,在e.target.value中可以取到它*/}
					{/*checked用于表单受控*/}
					<span>选择性别:</span>
					<input 
						type="radio" 
						name="gender"
						value="1"
						checked={gender==1} 
						onChange={this.change.bind(this,"gender")}
					/>
					<label></label>
					<input 
						type="radio" 
						name="gender"
						value="2"
						checked={gender==2} 
						onChange={this.change.bind(this,"gender")}
					/>
					<label></label>
				</div>
				
				<div>
					<span>选择学历:</span>
					<select value={grade} onChange={this.change.bind(this,"grade")}>
						{
							gradeArr.map(ele=>(
								<option 
									key={ele.id} 
									value={ele.id}
								>
									{ele.label}
								</option>
							))
						}
					</select>
				</div>
				<div>
					<input type="checkbox" checked={agree} onChange={this.change.bind(this,"agree")}/>
					<label>是否同意该注册协议</label>
				</div>
				<button onClick={this.submitAll.bind(this)}>提交</button>
			</div>
		)
}

你可能感兴趣的:(react,react,概念数据模型)