react基础组件的使用

本文详细介绍了React的基础知识,包括jsx的基本使用,如jsx的意义、语法规则和注意事项;组件的创建,包括函数式组件和es6类组件的定义;组件的属性,如构造器、props和refs的使用;以及组件的组合和一些重点知识,如call、apply、bind的区别和三点运算符的应用。此外,还讲解了ES6类的特性以及React中类组件的继承概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

react基础

一、jsx基本使用

1、简单的react案例
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello React</title>

</head>

<body>
  <div id='demo'> </div>

  <!-- react核心库 -->
  <script src="../js/react.development.js"></script>
  <!-- 虚拟dom -->
  <script src="../js/react-dom.development.js"></script>
  <!-- 翻译:es6=>es5  , jsx=>js -->
  <script src="../js/babel.min.js"></script>

  <!-- 要把type="text/JavaScript"改为type="text/babel" -->
  <script type="text/babel">
    // 创建虚拟dom
  const VDOM = <h1>hello react</h1>  //此处VDOM不是字符串,不用加引号,jsx语法中可以写标签
  //通过react渲染虚拟dom
  // ReactDOM.render('渲染对象','渲染到哪')
  ReactDOM.render(VDOM,document.getElementById('demo'))
  
  /*
      虚拟DOM:
      1、虚拟DOM是一个普通的object对象


      2、虚拟DOM和真实DOM的区别
      const VDOM = <h1>hello react</h1>
      const DOM = document.getElementById('demo');
      console.log(VDOM);
      console.log(trueDOM);
      在debug模式下可发现:VDOM对象中包含的内容比trueDOM少的多

      (1).虚拟DOM比较“轻”,真实DOM比较“重”
      (2).虚拟DOM是react在用的,无需真实DOM身上那么多的属性。
   */  
  </script>
</body>

</html>
2、原生创建虚拟DOM
<!-- 使用原生js创建虚拟DOM -->
<script type="text/javascript">
const myId = 'AtGuigU'
const myContent = 'HeLlO,ReAct'

//1.创建虚拟DOM
//React.createElement(标签名,标签属性,内容)
const VDOM = React.createElement('h1',{id:myId.toLowerCase()},React.createElement('span',{},myContent.toLowerCase()))

//2.渲染虚拟DOM
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
3、jsx创建虚拟DOM
<script type="text/babel" >

const myId = 'AtGuigU'
const myContent = 'HeLlO,ReAct'

//1.创建虚拟DOM
//React.createElement(标签名,标签属性,内容)
const VDOM = (
              <div>
                <h1 id={myId.toLowerCase()} zhangsan="qunideba">
                  <span className="title" style={{fontSize:'50px'}}>
                    {myContent.toLowerCase()}
                  </span>
                </h1>
                <h2>1121</h2>
                <input type="text"/>
              </div>
              )

//2.渲染虚拟DOM
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
注意:

关于jsx你要知道的:
1.jsx存在的意义:让程序员更加方便的创建虚拟DOM,几乎和写html是一样的。
2.jsx语法经过babel的编译,一定会转为原生js的语法。
3.jsx语法规则:
1.不要写引号,不是字符串
2.标签里要混入js表达式,要这样:{js表达式}
3.样式不要写class,要写className
4.style的写法:style={{}}
5.必须只有一个跟标签
6.所有标签必须闭合

二、组件的基本使用

1、函数式定义组件
jsx解析标签规则:

1、发现<Demo/>的首字母是大写。会去寻找Demo组件定义的位置

2、发现首字母是小写。
2.1 且有同名的HTML标签,会直接转化为HTML标签
2.2 没有同名的HTML标签,也会正常渲染为HTML标签,但是控制台会报错

3、react帮我们调用Demo函数,并获取到Demo函数的返回值。

4.把返回的虚拟DOM,转换成真实DOM,放入指定容器。

//1.定义组件(函数式定义)---简单的组件用函数式定义
function Demo() {
  console.log(this); //此处的this是undefined,因为经过babel编译之后开启了严格模式。
  return <h1>我是用函数定义的组件(简单组件用我定义)</h1>
}
//2.渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('example'))
/* 
2、使用es6类定义组件
案例:
//1.定义组件(用ES6类定义)-------复杂组件
class Demo extends React.Component{
  //该render和ReactDOM.render没有关系,仅仅是名字的重合。
  render(){ //render是放在哪里的?--- Demo的原型对象上的,Demo的实例可以调用到
    console.log(this);//Demo的实例
    return <h1>我是ES6类定义的组件(复杂组件用我定义)</h1>
  }
}
//2.渲染组件
ReactDOM.render(<Demo/>,document.getElementById('example'))
/* 

三、组件实例的三个属性

1、state
使用构造器创建state

注1:
//demo为类中的方法
1.demo是放在原型上的。
2.demo中的this是undefined
3.this为undefined的原因:由于demo不属于react生命周期函数。
备注:在组件类中,所有非react生命周期函数中的this都被react更改了this,变为了undefined。

注2:
关于修改state要注意:
1.状态不可以直接修改,即:不能使用这种方式 this.state.isHot = xxxx
2.要调用一个内置的setState()方法去更新状态

注3:
1.render是放在原型上的。
2.render中的this是类的实例对象。
3.由于render是react众多生命周期函数中的一个。
备注:react所有生命周期函数中的this都是组件的实例对象。

案例:
class Weath extends React.Component{
  constructor(){
    super()
    this.state ={
      isHot:true
    }
    this.toWeath = this.toWeath.bind(this)//改变类中的toWeath方法的this执行,并传递给类的实例
  }
  toWeath(){
    // console.log(this); //未改变this指向前,输出为undefined
    const isHot = this.state.isHot
    this.setState({isHot:!isHot})
  }

  render(){
    // console.log(this);render为react的生命周期函数,内部this指向类的实例

    return(
      <div>
        <h1>213{this.state.isHot?'热':'不热'}</h1>
        <h2  onClick={this.toWeath}>点击改变</h2>
      </div>
    )
  }
}

ReactDOM.render(<Weath/>,document.getElementById('demo'))
简写方式

注意:类中写赋值语句,代表的是向实例对象身上追加一个属性
形如: a = 1 代表向实例对象身上追加一个属性 名为a,值为1

另外:自己定义的非生命周期函数要写赋值语句,且函数要写箭头函数。
所以上面的代码可以简写为:

class Weath extends React.Component{
//state可以直接写赋值语句
state ={
    isHot:true
  }
//自己定义的非生命周期函数要写赋值语句,且函数要写箭头函数。
toWeath =()=>{
  const isHot = this.state.isHot
  this.setState({isHot:!isHot})
}

render(){
  return(
    <div>
      <h1>213{this.state.isHot?'热':'不热'}</h1>
      <h2  onClick={this.toWeath}>点击改变</h2>
    </div>
  )
}
}

ReactDOM.render(<Weath/>,document.getElementById('demo'))
2、props
在渲染时传入数据

注1:使用ReactDOM.render(<Weath/>,···)渲染时,可以传入数据

ReactDOM.render(<Weath name:“23” />,···)

注2:react + babel 就可以让三点运算符展开一个对象,但是仅适用于标签属性。

ReactDOM.render(<Weath {…p1} />,···)

注3:注意区分原生js中的{...p1}

案例:

ReactDOM.render(<Weath name="李四" age={12} />,document.getElementById('demo1'))
ReactDOM.render(<Weath {...p} />,document.getElementById('demo2'))
对props中的属性值进行类型限制和必要性限制

weath为组件类
第一种方式(React v15.5 开始已弃用):

Weath.propTypes = {
 name: React.PropTypes.string.isRequired,
 age: React.PropTypes.number
}

第二种方式(新):
使用prop-types库进限制(需要引入prop-types库)

Weath.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number. 
}
指定传递标签属性的默认值
Weath.defaultProps = {
  sex:'女'
}

static设置类的方法为静态的,不会传递给实例化对象

3、refs与事件处理
三种方式

普通ref方式(官方不推荐过多使用)

class Demo extends React.Component{

		test1 = ()=> {
			//1.获取左侧input的内容
			const {value} = this.refs.left
			//2.alert内容
			alert(value)
		}

		test2 = (event)=>{
			alert(event.target.value);
		}

		render(){
			return (
				<div>
					<input type="text" ref="left"/>&nbsp;
					<button onClick={this.test1}>点我提示左侧数据</button>&nbsp;
					<input onBlur={this.test2} type="text" placeholder="失去焦点提示数据"/>
				</div>
			)
		}
	}

	//2.渲染组件
	ReactDOM.render(<Demo/>,document.getElementById('example'))

新语法:回调ref

class Demo extends React.Component{

		test1 = ()=> {
			alert(this.left.value)
		}

		test2 = (event)=>{
			alert(event.target.value);
		}

		render(){
			return (
				<div>
					<input type="text" ref={currentNode => this.left = currentNode}/>&nbsp;
					<button onClick={this.test1}>点我提示左侧数据</button>&nbsp;
					<input onBlur={this.test2} type="text" placeholder="失去焦点提示数据"/>
				</div>
			)
		}
	} 

	//2.渲染组件
	ReactDOM.render(<Demo/>,document.getElementById('example'))

新语法:createRef 创造容器保存节点(只能保存一个节点)

class Demo extends React.Component{
		//React.createRef()会创造一个容器,这个容器专门用于保存节点,且这容器只能保存一个节点。
		myRef = React.createRef()
		
		test1 = ()=> {
			console.log(this.myRef.current);
		}

		test2 = (event)=>{
			alert(event.target.value);
		}

		render(){
			return (
				<div>
					<input type="text" ref={this.myRef}/>&nbsp;
					<button onClick={this.test1}>点我提示左侧数据</button>&nbsp;
					<input onBlur={this.test2} type="text" placeholder="失去焦点提示数据"/>
				</div>
			)
		}
	}

	//2.渲染组件
	ReactDOM.render(<Demo/>,document.getElementById('example'))

四、组件的组合使用

拆分组件:

需要一个外壳组件和内部负责不同功能的组件
把内部组件放在外壳组件中,这样只需要渲染外壳组件即可

案例:

//定义App组件,他是所有组件的“外壳”
		class App extends React.Component{
			render(){
				return (
					<div>
						<h1>Simple Todo List</h1>
						<Add/>
						<List/>
					</div>
				)
			}
		}

		//定义Add组件---用于添加的
		class Add extends React.Component{
			render(){
				return (
					<div>
						<input type="text"/>
						<button>Add#xxxx</button>
					</div>
				)
			}
		}

		//定义Add组件---用于添加的
		class List extends React.Component{
			render(){
				return (
					<ul>
						<li>吃饭</li>
						<li>睡觉</li>
						<li>打海峰</li>
					</ul>
				)
			}
		}

		//渲染组件
		ReactDOM.render(<App/>,document.getElementById('example'))

end:一些重点知识

1、call,apply,bind的区别

call :调用函数+改变this指向 传参
apply :调用函数+改变this指向
bind :改变this指向,返回新函数

2、三点运算符
三点运算符的作用:

解构数组:

 let arr = [4,5,6,7]
	let obj = {name:'peiqi',age:18,sex:{option1:'男',option2:'女'}}

  console.log(...arr);//输出 4 5 6 7
  // console.log(...obj);// 报错:demo.html:36 Uncaught TypeError: Found non-callable @@iterator

  console.log({...obj});//输出的是一个和原对象内容相同的新对象 

  console.log({...obj}===obj);//输出:false


	let obj2 = {...obj} //ES8的新语法--复制对象
	console.log(obj2);//obj2和obj内容相同,但指向不是同一个

3、ES6的类
类里面能写什么?
1.构造器(非必须)
```
constructor(name,age){
  //一般向实例身上追加属性
  this.name = name
  this.age = age
}
```
2.方法(非必须)
speak(){ //speak是放在类原型上的,供类的实例用。
  console.log(`我是${this.name},我的年龄是:${this.age}`);
}
3.赋值语句(非必须),

形如: a = 1 ,含义是:向实例对象身上追加一个属性,名为a,值为1

类的继承

class 类名 extends 父类名

注意:如果A类继承了B类,那么在A类的构造器中就必须要调用super

4、js语句js表达式
一定注意区分:【js语句】 与 【js表达式】:
1.表达式:一个表达式会产生一个值,它可以放在任何需要一个值的地方
  举例:a
        3 + b
        demo("a", "b")
        arr.map()
        function foo() {}
        .....
2.语句:语句可以理解成一个行为,循环语句、if语句,都是典型的语句
  举例:
        if(){}
        for(){}
        ......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值