1.react.js:React核心库。
2.react-dom.js:提供操作DOM的react扩展库。
3.babel.min.js:解析JSX语法代码转为JS代码的库。
注意: 核心库必须在扩展库之前引入
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<!-- 此处一定要写babel,不写默认是text/javascript -->
<!-- 使用babel用于将jsx转换为js -->
<script type="text/babel"> //1.创建虚拟dom //jsx语法 const VDOM=<h1>大忽悠</h1>//此处一定不要写引号,因为不是字符串 //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<!-- 此处一定要写babel,不写默认是text/javascript -->
<!-- 使用babel用于将jsx转换为js -->
<script type="text/babel"> //1.创建虚拟dom const VDOM=<h1 id="test">大忽悠</h1>//此处一定不要写引号,因为不是字符串 //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
</body>
</html>
js创建虚拟dom,就不需要引入babel的js库来解析jsx语法了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 此处一定要写babel,不写默认是text/javascript -->
<!-- 使用babel用于将jsx转换为js -->
<script type="text/javascript"> //1.创建虚拟dom //标签名,标签属性,标签内容 const VDOM=React.createElement('h1',{id:'title'},'大忽悠'); //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
</body>
</html>
js写法:
<script type="text/javascript"> //1.创建虚拟dom //标签名,标签属性,标签内容 const VDOM=React.createElement('h1',{id:'title'}, React.createElement('span',{id:'heihei'},'大忽悠')); //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
jsx写法:
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel"> //1.创建虚拟dom //标签名,标签属性,标签内容 const VDOM=( <h1 id='test'> <span id='heihei'>大忽悠</span> </h1>) //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
babel会把jsx语法写的html标签内容,翻译为js写法,相当于一种语法糖
1.React提供了一些API来创建一种 “特别” 的一般js对象
const VDOM = React.createElement('xx',{id:'xx'},'xx')
上面创建的就是一个简单的虚拟DOM对象
2.虚拟DOM对象最终都会被React转换为真实的DOM
3.我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界。
React.createElement(component, props, ...children)方法的语法糖
1)写法:var ele = < h1 >Hello JSX!< /h1 >
2)注意1:它不是字符串, 也不是HTML/XML标签
3)注意2:它最终产生的就是一个JS对象
1)遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
2)遇到以 { 开头的代码,以JS语法解析: 标签中的js表达式必须用{ }包含
<script type="text/babel">
const id="dhy";
const text="大忽悠和小朋友"
const VDOM=(
<h1 id={id}>
<span id='heihei'>{text}</span>
</h1>)
//2.渲染虚拟dom到页面
ReactDOM.render(VDOM,document.getElementById("test"));
</script>
class是ES6语法里面定义类的关键字
const VDOM=(
<h1 id={id}>
<span class='heihei'>{text}</span>
</h1>)
const VDOM=(
<h1 id={id}>
<span className='heihei'>{text}</span>
</h1>)
const VDOM=(
<h1 id={id}>
<font style={{color:'pink',fontSize:'29px'}}>小朋友</font>
</h1>)
此时最外层的div作为根标签
const VDOM=(
<div>
<h1 id={id}>
<font style={{color:'pink',fontSize:'29px'}}>小朋友</font>
</h1>
<h1 id={id+'1'}>
<font style={{color:'pink',fontSize:'29px'}}>大忽悠</font>
</h1>
</div>
)
错误,input标签没有闭合
const VDOM=(
<input type='text'>
)
正确,标签都闭合了
const VDOM=(
<input type='text'/>
)
(1):若小写字母开头,则将标签转换为html中同名标签元素,若html中无该标签对应的同名元素,则爆错
(2):若大写字母开头,react就去渲染对应的组件,若组件没有定义,则爆错
1.表达式: 一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些都是表达式:
(1) a
(2) a+b
(3) demo(1)
(4) arr.map()
(5) function test(){}
2.语句(代码):
(1)if(){}
(2) for(){}
(3)switch(){case:xxx}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel"> //模拟一些数据 const data=['dhy','xpy'] //创建虚拟DOM const VDOM= ( <div> <h1>前端js框架列表</h1> <ul> { //返回得到一个新数组 //由react遍历当前得到的新数组 data.map((item,index)=> { //读取遍历当前数组的变量值 //每个li必须有自己的唯一标识,即key对应的值,并且key值不可以重复 return <li key={index}>{item}</li> }) } </ul> </div> ) //2.渲染虚拟dom到页面 ReactDOM.render(VDOM,document.getElementById("test")); </script>
</body>
</html>
1.理解:向外提供特定功能的js程序, 一般就是一个js文件
2.为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
3.作用:复用js, 简化js的编写, 提高js运行效率
1.理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
2.为什么要用组件: 一个界面的功能更复杂
3.作用:复用编码, 简化项目编码, 提高运行效率
当应用的js都以模块来编写的, 这个应用就是一个模块化的应用
当应用是以多组件的方式实现, 这个应用就是一个组件化的应用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel"> //创建函数式组件 //函数组件的名字,首字母大写 function Demo() { //babel编译后,会开启严格模式,因此函数组件中的this指向undefined console.log(this); //必须有返回值 return <h1>函数组件</h1> } //渲染组件到页面 // 函数组件的标签首字母要大写,自闭合 ReactDOM.render(<Demo/>,document.getElementById('test')) </script>
</body>
</html>
1.React解析组件标签,找到了MyComponent组件
2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转换为真实DOM,随后呈现在页面中
<script type="text/javascript"> //创建一个Person类 class Person { //构造器方法 constructor(name,age) { //构造器中的this执行类的实例对象 this.name=name; this.age=age; } //一般方法 speak() { //speak方法放在了类的原型对象上,供实例使用 //通过Person实例调用speak时,speak中的this就是Person实例 //模板字符串 console.log(`姓名:${this.name},年龄:${this.age}`); } } //创建一个Student类,继承自Person class Stu extends Person { constructor(name,age,grade) { //此处必须调用父类的super方法 super(name,age); this.grade=grade; this.friend='小朋友'; } //重写从父类继承过来的方法 speak() { console.log(`姓名:${this.name},年龄:${this.age} ,年级:${this.grade}`); } } </script>
总结:
//创建类式组件---继承React.Component
class MyComponent extends React.Component
{
//render是放在MyComponent的原型对象上的,供实例使用
//this是MyComponent 的实例对象
//<==>MyComponent组件实例对象
render()
{
return <h2>类组件</h2>
}
}
//渲染组件到页面
ReactDOM.render(<MyComponent/>,document.getElementById('test'));
1.React解析组件标签,找到了MyComponent组件
2.发现组件是使用类定义的,随后调用该类的实例,并通过该实例调用到原型上的render方法
3.将render返回的虚拟DOM转换为真实DOM,随后呈现在页面中
1.默认展示天气炎热 或 凉爽
2.点击文字切换天气
常用的两种写法:
class Weather extends React.Component
{
constructor(props)
{
super(props)
//初始化状态
this.state={isHot:false}
}
render()
{
//读取状态
const {isHot}=this.state
return <h2 id="w">今天天气{isHot?'炎热':'凉爽'}</h2>
}
}
//渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'));
const w1=document.getElementById('w');
w1.addEventListener('click',()=>{
console.log('标题被点击了');
})
const w2=document.getElementById('w');
w2.onclick=()=>{
console.log('标题被点击了');
}
推荐写法:
class Weather extends React.Component
{
constructor(props)
{
super(props)
//初始化状态
this.state={isHot:false}
}
render()
{
//读取状态
const {isHot}=this.state
return <h2 onClick={demo}>今天天气{isHot?'炎热':'凉爽'}</h2>
}
}
//渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'));
function demo()
{
console.log('标题点击')
}
const { xxx } = this.state;
上面的写法是es6的写法,其实就相当于:
const xxx = this.state.xxx
开启了严格模式,那么方法里面的this为undefined
class A
{
s()
{
//s方法放在了类的原型对象上,供实例使用
//通过A的实例对象调用s方法时,s中的this就是A的实例
//否则为undefined
console.log(this)
}
}
const a=new A();
let b=a.s
b()
直接调用函数,函数中的this默认指向window,如果全局开启了严格模式,或者在函数体内部局部开启了严格模式,那么函数中的this为undefined
例如:
function a(){
'use strict'
console.log(this);
}
a();
function b(){
console.log(this);
}
b();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
// babel也会默认开启严格默认
class Weather extends React.Component
{
constructor(props)
{
super(props)
//初始化状态
this.state={isHot:false}
}
render()
{
//读取状态
const {isHot}=this.state
return <h2 onClick={this.changeWeather}>今天天气{isHot?'炎热':'凉爽'}</h2>
}
changeWeather()
{
//changeWeather放在weather的原型对象上,供实例使用
//由于changeWeather是作为onClick的回调
//所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式
//所以changeWeather中的this为undefined
console.log(this)
}
}
//渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'));
</script>
</body>
</html>
// babel也会默认开启严格默认
class Weather extends React.Component
{
//构造函数里面的this指向调用的实例对象
constructor(props)
{
super(props)
//初始化状态
this.state={isHot:false}
//解决changeWeather中的this指向问题
this.changeWeather=this.changeWeather.bind(this)
}
render()
{
//读取状态
const {isHot}=this.state
//现在当前类上寻找changeWeather方法,找不到再去原型上找
return <h2 onClick={this.changeWeather}>今天天气{isHot?'炎热':'凉爽'}</h2>
}
changeWeather()
{
//changeWeather放在weather的原型对象上,供实例使用
//由于changeWeather是作为onClick的回调
//所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式
//所以changeWeather中的this为undefined
console.log(this)
}
}
//严重注意,状态state不可直接更改
//下面这行就是直接更改,下面是错误的写法
this.state.isHot=!isHot;
// babel也会默认开启严格默认
class Weather extends React.Component
{
//构造函数里面的this指向调用的实例对象
//构造器调用一次
constructor(props)
{
super(props)
//初始化状态
this.state={isHot:false,wind: '微风'}
//解决changeWeather中的this指向问题
this.changeWeather=this.changeWeather.bind(this)
}
//render调用1+n次
//1是初始化的那次
//n是状态更新的次数
render()
{
//读取状态
const {isHot,wind}=this.state
//现在当前类上寻找changeWeather方法,找不到再去原型上找
return <h2 onClick={this.changeWeather}>今天天气{isHot?'炎热':'凉爽'}
,{wind}</h2>
}
//事件触发几次,就调用几次
changeWeather()
{
//获取原来的isHot的值
const isHot=this.state.isHot;
//状态必须通过setState进行更新,且更新时一种合并,不是替换
this.setState({isHot:!isHot})
}
}
//渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'));
点击后
class A
{
constructor(name) {
this.name=name;
}
//类中可以直接写赋值语句,相当于给实例对象增添了一个属性
//名为a,值为1
a=1
}
const a1=new A("大忽悠");
<script type="text/babel">
class Weather extends React.Component
{
//初始化状态
this.state={isHot:false,wind: '微风'}
render()
{
const {isHot,wind}=this.state
return <h2 onClick={this.changeWeather}>今天天气{isHot?'炎热':'凉爽'}
,{wind}</h2>
}
//自定义方法---要用赋值语句的形式+箭头函数
//箭头函数里面的this就是实例对象
//changeWeather此时是一个属性,指向一个方法,放在了实例对象上
changeWeather=()=>
{
const isHot=this.state.isHot;
this.setState({isHot:!isHot})
}
}
ReactDOM.render(<Weather/>,document.getElementById('test'));
</script>
1.state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
2.组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
1.组件中render方法中的this为组件实例对象
2.组件自定义的方法中this为undefined,如何解决?
a)强制绑定this: 通过函数对象的bind()
b)箭头函数
3.状态数据,不能直接修改或更新
效果:
class Person extends React.Component
{
render()
{
const {name,age}=this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
</ul>
)
}
}
ReactDOM.render(<Person name="bob" age="18"/>,document.getElementById('test'));
1.每个组件对象都会有props(properties的简写)属性
2.组件标签的所有属性都保存在props中
1.通过标签属性从组件外向组件内传递变化的数据
2.注意: 组件内部不要修改props数据
//展开数组
let arr1=[1,2,3]
let arr2=[4,5,6]
console.log(...arr1)
//连接数组
let arr3=[...arr1,...arr2]
//在函数中使用--只能作为最后一个参数使用
function sum(...nums)
{
return nums.reduce((preValue,curValue)=>{
return preValue+curValue
},0)//0是初始累加值
}
console.log(sum(1,2,3))
//构造字面量对象时使用展开语法
let person={name: 'tom',age: 18}
//展开对象必须在{}中使用
let per={...person}
console.log(per)
//合并对象
let per3={...person,name: 'jack'}
console.log(per3)
等同写法:
//展开对象必须在{}中使用
console.log({...person})
//合并对象
console.log({...person,name: 'jack'})
class Person extends React.Component
{
render()
{
const {name,age}=this.props;
return (
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
</ul>
)
}
}
const p={name:'大忽悠',age: '18'}
//...p只能在标签里面使用,外部使用会报错
//babel可以解析标签里面的...p
ReactDOM.render(<Person {...p}/>,document.getElementById('test'));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script type="text/javascript" src="./js/prop-types.js"></script>
<script type="text/babel"> class Person extends React.Component { render() { const {name,age,speak}=this.props; return ( <ul> <li>姓名:{name}</li> <li>年龄:{age}</li> </ul> ) } } //对标签属性进行类型,必要性的限制 Person.propTypes= { //限制name必须传,且为字符串 name:PropTypes.string.isRequired, //限制年龄为数字类型 age:PropTypes.number, //限制speak必须为函数类型 //这里用func表示函数类型,而不是function //因为function是js中的关键字 speak: PropTypes.func } //指定默认标签属性值 //如果标签里面没传对应的属性,那么赋予属性默认值 Person.defaultProps= { age: 18 } function speak() { return "dhy like xpy"; } ReactDOM.render(<Person name="小盆友" age={3} speak={speak}/>,document.getElementById('test1')); ReactDOM.render(<Person name="超级大忽悠"/>,document.getElementById('test2')); const p={name:'大忽悠',age:18} //...p只能在标签里面使用,外部使用会报错 ReactDOM.render(<Person {...p}/>,document.getElementById('test3')); </script>
</body>
</html>
class Person extends React.Component
{
render()
{
const {name,age,speak}=this.props;
//props是只读的,下面写法会报错
this.props.name="匿名"
return (
<ul>
<li>姓名:{name}</li>
<li>年龄:{age}</li>
</ul>
)
}
}
实例对象身上没有b属性,类身上才有
class A
{
constructor(a) {
this.a=a;
}
//给实例对象上身上添加属性
a=1;
static b=2
}
const a=new A(10);
console.log(a);
如何给类身上添加属性:
方法一:
class A
{
//给实例对象上身上添加属性
a=1;
}
//给class类自身加上属性
A.b=2;
console.log(A);
console.log(A.b)
方法二: static方法
class A
{
constructor(a) {
this.a=a;
}
//给实例对象上身上添加属性
a=1;
static b=2
}
console.log(A);
console.log(A.b);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello_React</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script type="text/javascript" src="./js/prop-types.js"></script>
<script type="text/babel"> class Person extends React.Component { render() { const {name,age}=this.props; return ( <ul> <li>姓名:{name}</li> <li>年龄:{age}</li> </ul> ) } static propTypes= { name:PropTypes.string.isRequired, age:PropTypes.number } static defaultProps= { age: 18 } } ReactDOM.render(<Person name="小盆友" age={3}/>,document.getElementById('test1')); ReactDOM.render(<Person name="超级大忽悠"/>,document.getElementById('test2')); </script>
</body>
</html>
如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
constructor(props)
{
//构造器是否接受props,是否传递给super,取决于是否希望构造器中调用
//this访问props
super(props);
//如果super(),那么this.props是undefined
console.log(this.props)
}
//创建函数式组件
function Per(props)
{
const {name,age}=props
return (
<ul>
<li>{name}</li>
<li>{age}</li>
</ul>
)
}
Per.propTypes={
name:PropTypes.string.isRequired,
age:PropTypes.number
}
Per.defaultProps=
{
age: 18
}
//渲染组件到页面
ReactDOM.render(<Per name="大忽悠"/>,document.getElementById('test'))
1.内部读取某个属性值
this.props.name
2.对props中的属性值进行类型限制和必要性限制
第一种方式(React v15.5 开始已弃用):
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number
}
第二种方式(新):使用prop-types库进限制(需要引入prop-types库)
Person.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.
}
3.扩展属性: 将对象的所有属性通过props传递
<Person {...person}/>
4.默认属性值:
Person.defaultProps = {
age: 18,
sex:'男'
}
5.组件类的构造函数
constructor(props){
super(props)
console.log(props)//打印所有属性
}
6.props为只读,不可以修改
7.函数式组件可以通过参数获取到props对象,然后进行操作,也可以进行类型和默认值操作
8.PropTypes大写的这个是导入js包后,全局新增的一个对象,而Person.propTypes是我们需要给类上添加的一个属性,react底层会去寻找当前类上名字相同的属性,然后进行遍历,设置对应的类型限制和默认值
//创建组件
class Demo extends React.Component
{
showData=()=>
{
//refs里面的input1属性对应input标签的dom对象
const{input1}=this.refs;
input1.value="大忽悠到此一游";
}
showData2=()=>
{
const{input2}=this.refs;
input2.value="呜呜呜";
}
render()
{
return (
<div>
<input ref="input1" type="text" placeholder='点击按钮提示数据'/>
<button onClick={this.showData}>点我提示左侧数据</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder='失去焦点,提示数据'/>
</div>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
//创建组件
class Demo extends React.Component
{
showData=()=>
{
const{input1}=this;
input1.value="大忽悠到此一游";
}
showData2=()=>
{
const{input2}=this;
input2.value="呜呜呜";
}
// c就是当前的input标签的dom对象
//将其挂载到当前实例上的input1属性上
render()
{
return (
<div>
<input ref={c=>this.input1=c} type="text" placeholder='点击按钮提示数据'/>
<button onClick={this.showData}>点我提示左侧数据</button>
<input ref={c=>this.input2=c} onBlur={this.showData2} type="text" placeholder='失去焦点,提示数据'/>
</div>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
如下的内联函数,每次渲染都会创建一个新的,并且先清空之前的ref,传入null,第二次传入dom元素
<input ref={c=>this.input1=c} type="text" placeholder='点击按钮提示数据'/>
如果是class的绑定函数,那么react就知道当前绑定函数被调用过,不会新创建函数实例,也就不会在更新的时候调用对应的函数了
React 初学 - 回调ref中调用次数的问题 - 个人笔记26
createRef创建出来的容器,只能放一个dom元素,后放进去的dom元素会覆盖之前放入的dom元素
//创建组件
class Demo extends React.Component
{
//React.createRef调用后返回一个容器
//该容器可以存储ref所标识的节点,该容器是专人专用
//后来的覆盖之前的
myref=React.createRef()
showData=()=>
{
console.log(this.myref)
}
//将input标签放入myref容器中
//如果将button也放入myref容器中
//那么会覆盖之前的input
render()
{
return (
<div>
<input ref={this.myref} type="text" placeholder='点击按钮提示数据'/>
<button ref={this.myref} onClick={this.showData}>点我提示左侧数据</button>
</div>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
1.通过onXxx属性指定事件处理函数(注意大小写)
1)React使用的是自定义(合成)事件, 而不是使用的原生DOM事件----为了更好的兼容性
2)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)---为了高效
2.通过event.target得到发生事件的DOM元素对象
当发生事件的元素正好是我们需要操作的元素时,ref可以不写,通过event可以获取到对应的dom元素
//创建组件
class Demo extends React.Component
{
showData=(event)=>
{
console.log(event.target)
}
render()
{
return (
<div>
<input ref={this.myref} type="text" placeholder='点击按钮提示数据'/>
<button onClick={this.showData}>点我提示左侧数据</button>
</div>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
//创建组件
class Demo extends React.Component
{
handleSubmit=(event)=>
{
//阻止表单提交
event.preventDefault()
const{nameInput,pwdInput}=this
//模板字符串
alert(`输入的用户名:${nameInput.value},输入的密码:${pwdInput.value}`)
}
render()
{
return(
<form onSubmit={this.handleSubmit}>
用户名: <input ref={c=>this.nameInput=c} type="text" name="username"/><br/>
密码: <input ref={c=>this.pwdInput=c} type="password" name="password"/><br/>
<button>登录</button>
</form>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
//创建组件
class Demo extends React.Component
{
//初始化状态
state={
name: '',
pwd: ''
}
//保存用户名到状态中
saveName=(event)=>
{
this.setState({name:event.target.value})
}
//保存密码到状态中
savePwd=(event)=>
{
this.setState({pwd:event.target.value})
}
handleSubmit=(event)=>
{
//阻止表单提交
event.preventDefault()
const{name,pwd}=this.state
alert(`输入的用户名:${name},输入的密码:${pwd}`)
}
render()
{
return(
<form onSubmit={this.handleSubmit}>
用户名: <input onChange={this.saveName} type="text" name="username"/><br/>
密码: <input onChange={this.savePwd} type="password" name="password"/><br/>
<button>登录</button>
</form>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数
let a='name'
let obj={name:"大忽悠"}
console.log(obj[a])
//下面是错误写法
console.log(obj.a)
//创建组件
class Demo extends React.Component
{
//初始化状态
state={
name: '',
pwd: ''
}
//保存表单数据到状态中
saveFormData=(dataType)=>{
return (event)=>
{
//[]是读取变量里面的值
this.setState({[dataType]:event.target.value})
}
}
handleSubmit=(event)=>
{
//阻止表单提交
event.preventDefault()
const{name,pwd}=this.state
alert(`输入的用户名:${name},输入的密码:${pwd}`)
}
render()
{
return(
<form onSubmit={this.handleSubmit}>
用户名: <input onChange={this.saveFormData('name')} type="text" name="username"/><br/>
密码: <input onChange={this.saveFormData('pwd')} type="password" name="password"/><br/>
<button>登录</button>
</form>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
onChange事件这里接收到的是saveFormData函数的返回值,因为saveFormData函数的返回值还是一个函数,onChange调用返回的函数时,会往里面传入一个event对象
//创建组件
class Demo extends React.Component
{
//初始化状态
state={
name: '',
pwd: ''
}
//保存表单数据到状态中
saveFormData=(dataType,event)=>{
//[]是读取变量里面的值
this.setState({[dataType]:event.target.value})
}
handleSubmit=(event)=>
{
//阻止表单提交
event.preventDefault()
const{name,pwd}=this.state
alert(`输入的用户名:${name},输入的密码:${pwd}`)
}
render()
{
return(
<form onSubmit={this.handleSubmit}>
用户名: <input onChange={(event)=>{this.saveFormData('name',event)}} type="text" name="username"/><br/>
密码: <input onChange={(event)=>{this.saveFormData('pwd',event)}} type="password" name="password"/><br/>
<button>登录</button>
</form>
)
}
}
//渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'));
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/m0_53157173/article/details/120412892
内容来源于网络,如有侵权,请联系作者删除!