目录
简介
入门案例
直接创建
函数式创建
类实例创建
组件实例三大核心属性
state
代码演示
props
refs
简介
1). Facebook开源的一个js库
2). 一个用来动态构建用户界面的js库
3). React的特点
Declarative(声明式编码)
Component-Based(组件化编码)
Learn Once, Write Anywhere(支持客户端与服务器渲染)
高效
单向数据流
4). React高效的原因
虚拟(virtual)DOM, 不总是直接操作DOM(批量更新, 减少更新的次数)
高效的DOM Diff算法, 最小化页面重绘(减小页面更新的区域)
入门案例
直接创建
首选引入旧版所需js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
/**
* jsx语法:
* 1 定义虚拟dom时 不要加引号
* 2 标签中混入js表达式时要用{}
* 3 样式的类名不要用class 要用className
* 4 内联样式 要用style={{key:name}}形式写
* 5 只有一个根标签
* 6 标签必须闭合
* 7 标签首字母
* (1) 若小写字母开头 则将该标签转为html同名元素 若html中无该标签
* 对应的同名元素 则报错
* (2) 若大写字母开头 react就去渲染对应的组件 若组件没有定义 则报错
*
*
*/
const data = ['Vue','React','Angular']
//创建虚拟dom
const vdom = (
<div>
<h1 >hello react</h1>
<ul>{
data.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
</div>
)
//渲染 虚拟 dom到页面
ReactDOM.render(vdom,document.getElementById('test'))
</script>
</html>
</html>
所需js文件点击链接下载
点击下载 react资料
提取码:cowf
打开浏览器测试:
函数式创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//函数式创建虚拟dom
function MyCompent(){
return <h1> 这是一个函数组件化Dom</h1>
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
/*
执行流程
1 react解析组件标签 找到了MyCompemt组件
2 发现组件是使用函数定义的 随后调用该函数 将返回的虚拟dom转为真实dom 随后呈现在页面中
*/
</script>
</html>
类实例创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
render(){
console.log(this)
return <h1> 这是一个类定义的组件(适用于复杂组件的定义)</h1>
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
/*
执行流程
1 react解析组件标签 找到了MyCompemt组件
2 发现组件是使用类定义的 随后new出该类的实例 并通过该实例调用到原型上的render方法
3 将render返回的虚拟dom转化为真实dom 随后呈现在页面中
*/
</script>
</html>
组件实例三大核心属性
state
(1) state是组件对象最重要的属性 值是对象类型(可以包含多个 key:value的组合)
(2) 组件也被称为"状态机" 通过更新组件的state来更新对应的页面显示(重新渲染组件)
严格注意
(1) 组件中render方法中的this为组件实例对象
(2) 组件自定义的方法中 this指向为undefined 解决办法:
强制绑定this :通过函数对象的bind()
箭头函数 ()=>{}
(3) 状态数据 不能直接修改或更新 要使用 setState({key:value})来进行修改
代码演示
完整类版本(只做演示学习用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
//构造器只调用1次
constructor(props){
super(props)
this.state = {sunny:true}
//解决changeWeather中this的指向问题
this.changeWeather = this.changeWeather.bind(this)
}
//render调用 n+1次 1是初始化就调用了一次 n是状态更新的次数
render(){
//打印实例对象
console.log('打印实例对象');
console.log(this)
return <h1 onClick={this.changeWeather}>今天是{this.state.sunny ? '晴天':'阴天'}</h1>
}
//点击几次调用几次
changeWeather(){
//这里的changeWeather放在哪里? MyComponet原型对象上 供实例来使用
//由于 changeWeather是作为 onClick的回调 所以不是通过实例调用的 是直接调用
//类中的方法默认开启的了局部的严格模式 所以changeWeather中的this为undefined
//注意 : 状态必须通过setState 来进行更新
this.setState({sunny:!this.state.sunny})
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
当我们点击页面中的文字时,更改当前实例的state属性为false,则文字变为阴天
代码简化版本(开发主要用版本)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
state = {sunny:true}
//render调用 n+1次 1是初始化就调用了一次 n是状态更新的次数
render(){
console.log(this)
return <h1 onClick={this.changeWeather}>今天是{this.state.sunny ? '晴天':'阴天'}</h1>
}
//自定义方法 要用复制语句的形式+箭头函数
changeWeather = ()=>{
this.setState({sunny:!this.state.sunny})
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
效果和完整类版本一致
props
每个组件对象都会有props(properties简写) 属性
组件标签的所有属性都保存在props中
通过标签属性从组件外向组件内传递变化的数据
注意: 组件内部不可修改props数据
再引入一个js文件
类组件式props
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<!-- 引入 prop-types 用于对标签属性进行类型 必要性限制 -->
<script src="../js/prop-types.js"></script>
<body>
<div id="test"></div>
<div id="test2"></div>
<div id="test3"></div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
// //类式创建虚拟dom
class UltMan extends React.Component{
//对标签属性进行类型 必要性的限制
static propTypes = {
name:PropTypes.string.isRequired,//限制name必传 类型为字符串
sex:PropTypes.string,//设置性别为字符串
age:PropTypes.number,//设置age为数字
speak:PropTypes.func,//限制speak为函数
}
//设置标签属性默认值
static defaultProps = {
sex:'人妖',//sex默认值为人妖
age:0
}
render(){
const {name,age,sex} = this.props;
console.log(this)
return (
<ul>
<li>名字:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age+1}</li>
</ul>
)
}
}
//渲染 组件到页面
ReactDOM.render(<UltMan name='迪迦' sex='男' age={23}/>,document.getElementById('test'))
ReactDOM.render(<UltMan name='戴拿' />,document.getElementById('test2'))
const {name,sex,age} = {name:'盖亚',sex:'男', age:21}
ReactDOM.render(<UltMan name={name} sex={sex} age={age} speak={fangfa}/>,document.getElementById('test3'))
function fangfa(){}
</script>
</html>
函数组件式引用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<!-- 引入 prop-types 用于对标签属性进行类型 必要性限制 -->
<script src="../js/prop-types.js"></script>
<body>
<div id="test"></div>
<div id="test2"></div>
<div id="test3"></div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//函数式
function UltMan(props){
const {name,age,sex} = {...props}
return (
<div>
<h1>函数式组件使用props</h1>
<ul>
<li>名字:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age+1}</li>
</ul>
</div>
)
}
UltMan.propTypes = {
name:PropTypes.string.isRequired,//限制name必传 类型为字符串
sex:PropTypes.string,//设置性别为字符串
age:PropTypes.number,//设置age为数字
speak:PropTypes.func,//限制speak为函数
}
//设置标签属性默认值
UltMan.defaultProps = {
sex:'人妖',//sex默认值为人妖
age:0
}
//渲染 组件到页面
ReactDOM.render(<UltMan sex='男' age={23}/>,document.getElementById('test'))
ReactDOM.render(<UltMan name='梦比优斯' />,document.getElementById('test2'))
const {name,sex,age} = {name:'麦克斯',sex:'男', age:21}
ReactDOM.render(<UltMan name={name} sex={sex} age={age} speak={fangfa}/>,document.getElementById('test3'))
function fangfa(){}
</script>
</html>
refs
介绍
组件内的标签可以自定义ref属性来标识自己 通俗地讲就是拿取dom节点用的
演示
字符串refs
在标签上添加ref属性,然后打印当前this查看
可以看到可以通过refs属性拿取到dom节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
//展示上边输入框数据
showData = ()=>{
console.log(this)
const input1 = this.refs.input1
console.log(input1.value)
}
//展示下边输入框数据
showData2 =()=>{
//解构赋值写法
const {input2} = this.refs
alert(input2.value)
}
render(){
return (
<div>
<input ref='input1' placeholder='点击按钮弹出数据'/><br/>
<button onClick={this.showData}>点击提示上边的数据</button><br/>
<input onBlur={this.showData2} ref='input2' placeholder='失去焦点弹出数据'/>
</div>
)
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
这是旧版的string写法 官网已经不建议使用这种写法
回调refs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
//展示上边输入框数据
showData = ()=>{
console.log(this)
const input1 = this.input1
console.log(input1.value)
}
//展示下边输入框数据
showData2 =()=>{
//解构赋值写法
const {input2} = this
alert(input2.value)
}
render(){
return (
<div>
<input ref={(currentNode)=>{this.input1 = currentNode}} placeholder='点击按钮弹出数据'/><br/>
<button onClick={this.showData}>点击提示上边的数据</button><br/>
<input onBlur={this.showData2} ref={c=>this.input2 = c} placeholder='失去焦点弹出数据'/>
</div>
)
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
测试观察
注意此时的input节点并没有被refs所包裹,而是直接绑定在了reat实例对象上
测试效果和字符串refs都一致
关于回调refs的说明
如果ref回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数null,然后第二次会传入参数DOM元素。这是因为在每次渲染时会创建一个新的函数实例,所以React清空旧的ref并且设置新的。通过将ref的回调函数定义成class的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
问题演示:
添加之前切换天气的标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
//设置state属性
state = {sunny:true}
//展示上边输入框数据
showData = ()=>{
console.log(this)
const input1 = this.input1
console.log(input1.value)
}
//展示下边输入框数据
showData2 =()=>{
//解构赋值写法
const {input2} = this
alert(input2.value)
}
changeWeather=()=>{
//更新状态
this.setState({sunny:!this.state.sunny})
}
render(){
const isSunny = this.state.sunny;
return (
<div>
<h1>今天是{isSunny? '晴天':'阴天'}</h1>
<input ref={(currentNode)=>{this.input1 = currentNode;console.log('@',currentNode)}} placeholder='点击按钮弹出数据'/><br/>
<button onClick={this.showData}>点击提示上边的数据</button><br/>
<input onBlur={this.showData2} ref={c=>this.input2 = c} placeholder='失去焦点弹出数据'/>
<button onClick={this.changeWeather}>点击切换天气</button><br/>
</div>
)
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
启动测试:
可以看到刚启动时会执行一次input的内联回调函数
此时,我们再点击切换天气按钮
可以看到,回调函数被执行了两次,且第一次执行为null
这是因为在每次渲染时会创建一个新的函数实例,所以React清空旧的ref并且设置新的。(官网原话)
此时可以通过外联函数解决这个问题
再次测试
此时再点击切换天气就没有之前的问题了
但是大多数情况下它是无关紧要的。所以我们还是可以直接用内联函数的形式直接开发即可
最新方式 createRef()
可以看到直接打印出了input的节点文章来源:https://www.toymoban.com/news/detail-448077.html
文章来源地址https://www.toymoban.com/news/detail-448077.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 引入react核心库 -->
<script src="../js/react.development.js"></script>
<!-- 引入react-dom 用于支持react操作dom -->
<script src="../js/react-dom.development.js"></script>
<!-- 引入babel 用于将jsx转为js -->
<script src="../js/babel.min.js"></script>
<body>
<div id="test">
</div>
</body>
<!-- 这里一定要指明是babel类型 -->
<script type="text/babel">
//类式创建虚拟dom
class MyCompent extends React.Component{
//Reat.createRef 调用后可以返回一个容器 该容器可以存储被ref所标识的节点
myRef = React.createRef();
myRef2 = React.createRef();
//展示上边输入框数据
showData = ()=>{
console.log(this.myRef)
console.log(this.myRef.current.value)
}
//展示下边输入框数据
showData2 =()=>{
alert(this.myRef2.current.value)
}
render(){
return (
<div>
<input ref={this.myRef} placeholder='点击按钮弹出数据'/>
<button onClick={this.showData}>点击提示上边的数据</button><br/>
<input onBlur={this.showData2} ref={this.myRef2} placeholder='失去焦点弹出数据'/>
</div>
)
}
}
//渲染 组件到页面
ReactDOM.render(<MyCompent/>,document.getElementById('test'))
</script>
</html>
到了这里,关于一看就会的React入门的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!