目录
状态更新 修改state 【this.setState({isHot:!isHot});】
1 state
state里面存储对象格式key-value的数据 组件状态驱动页面
标准使用方式
//1.创建组件
class Weather extends React.Component{
constructor(props){
//构造器调用1次
super(props);
this.state = {isHot:true,win:"ss"};
//找到原型的dem,根据dem函数创建了一个dem1的函数,并且将实例对象的this赋值过去
// this.dem1 = this.dem.bind(this);
}
//render会调用1+n次【1就是初始化的时候调用的,n就是每一次修改state的时候调用的】
render(){ //这个This也是实例对象
//如果加dem(),就是将函数的回调值放入这个地方
//this.dem这里面加入this,并不是调用,只不过是找到了dem这个函数,在调用的时候相当于直接调用,并不是实例对象的调用
const {isHot}=this.state
return <h1 onClick = {this.changeWeather}>今天天气很{isHot?"炎热":"凉爽"}</h1>
}
//通过state的实例调用dem的时候,this就是实力对象
//类中的方法默认开启了严格模式,所以this是undefined
changeWeather = () =>{
const state = this.state.isHot;
//状态中的属性不能直接进行更改,需要借助API
// this.state.isHot = !isHot; 错误
//必须使用setState对其进行修改,并且这是一个合并
this.setState({isHot:!state});
}
}
// 2.渲染,如果有多个渲染同一个容器,后面的会将前面的覆盖掉
ReactDOM.render(<Weather />,document.getElementById("test"));
1 复习 :原生事件绑定
2 react事件绑定
-
onClick={this.changeWeather}
之前学的是οnclick="demo()"
但react是:
onClick={this.changeWeather}
changeWeather放在【weather的原型对象上,供实例使用】、
通过Weather实例调用changeWeather,changeWeather中的this就是【weather实例】
由于changeWeather是作为onClick的回调,所以不是通过实例调用,是直接调用、
类中的方法默认严格模式及,所以changeWeather中的this为undefined
构造器中的this【weather实例对象】
render中的this【weather实例对象】
-
状态更新 修改state 【this.setState({isHot:!isHot});】
类式组件方法中修改
dem = () =>{
const isHot = this.state.isHot;
//状态中的属性不能直接进行更改,需要借助API
// this.state.isHot = !isHot; 错误
//必须使用setState对其进行修改,并且这是一个合并
this.setState({isHot:!isHot});
}
- 构造器调用1次
render会调用1+n次【1就是初始化的时候调用的,n就是每一次修改state的时候调用的】
3 复习:类中方法的this指向
类中定义的方法已经开好的严格模式
直接调用 this 是window
严格模式 this 是undefined
const isHot = this.state.isHot;是将this.state.isHot的值赋给变量isHot。这种语法适用于从对象中提取单个属性,并将其赋值给新的变量。
而const {isHot} = this.state;使用了解构赋值语法,它实际上是从this.state对象中提取名为isHot的属性,并将其赋值给一个名为isHot的变量。这种语法允许你一次将多个属性从对象中提取出来并赋值给对应的变量。
总结来说,两者的主要区别在于语法和提取属性的方式。第一种方式是直接从对象获取属性的值并赋给变量,而第二种方式则是通过解构赋值从对象中提取属性并赋值给变量。
4 简写 箭头函数(掌握)
//1.创建组件
class St extends React.Component{
//类中可以直接写赋值语句 无需let
state = {isHot:true};
render(){ //这个This也是实例对象
const isHot = this.state.isHot;
return <h1 onClick = {this.dem}>今天天气很{this.state.isHot?"炎热":"凉爽"}</h1>
}
//箭头函数 [自定义方法--->要用赋值语句的形式+箭头函数] this为实例对象
dem = ()=>{
console.log(this);
const state = this.state.isHot;
this.setState({isHot:!state});
}
}
ReactDOM.render(<St />,document.getElementById("test"));
2 props
作用
1 通过标签属性从组件外向组件内传递变化的数据
2 注意组件内部不要修改props数据
1 复习:展开运算符
- 构造字面量对象时使用展开语法
- 赋值同时修改属性
2 限制
<!--引入对于组件标签的限制-->
<script src="../React-js/prop-types.js"></script>
Person.propTypes = {
name:PropTypes.string.isRequired,
sex:PropTypes.string,
age:PropTypes.number,
speak:PropTypes.func
}
//指定默认的标签属性
Person.defaultProps = {
sex:"不男不女",
age:18
}
3 简化
class Person extends React.Component{
render(){
//props是只读的
return (
<ul>
<li>{this.props.name}</li>
<li>{this.props.age}</li>
<li>{this.props.sex}</li>
</ul>
)
}
//对组件的属性对其进行限制
static propTypes = {
name:PropTypes.string.isRequired,
sex:PropTypes.string,
speak:PropTypes.func
}
//指定默认的标签属性
static defaultProps = {
sex:"不男不女",
age:18
}
}
//在js中可以使用{...p}来复制一个对象,但是这个地方并不是复制对象,而是babel+react通过展开运算符,展开了一个对象
//但是只能在标签中进行使用
//const p = {name:"张三",age:"18",sex:"女"} {14}就代表的是数值
ReactDOM.render(<Person name="sss" age = {14} speak={speak}/>,document.getElementById("div"));
//ReactDOM.render(<Person {...p}/>,document.getElementById("div"));
function speak(){
console.log("这个是一个函数")
}
4 constructor()
通常情况下,在react中,构造函数仅用于以下两种情况:
- 通过给this.state赋值对象来初始化内部state
- 为事件处理函数绑定实例
constructor(props){
super(props);
this.state = {isHot:true,win:"ss"};
//找到原型的dem,根据dem函数创建了一个dem1的函数,并且将实例对象的this赋值过去
// this.dem1 = this.dem.bind(this);
}
5 函数组件使用props
function Person(props){
// const{name,age,sex}=props
return (
<ul>
<li>{props.name}</li>
<li>{props.age}</li>
<li>{props.sex}</li>
</ul>
)
}
//对组件的属性对其进行限制
Person.propTypes = {
name:PropTypes.string.isRequired,
sex:PropTypes.string,
speak:PropTypes.func
}
//指定默认的标签属性
Person.defaultProps = {
sex:"不男不女",
age:18
}
//在js中可以使用{...p}来复制一个对象,但是这个地方并不是复制对象,而是babel+react通过展开运算符,展开了一个对象
//但是只能在标签中进行使用
//const p = {name:"张三",age:"18",sex:"女"} {14}就代表的是数值
ReactDOM.render(<Person name="sss" age = {14} speak={speak}/>,document.getElementById("div"));
//ReactDOM.render(<Person {...p}/>,document.getElementById("div"));
function speak(){
console.log("这个是一个函数")
}
3 refs
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
1 字符串形式的ref(不推荐)有效率问题
class Demo extends React.Component{
showData=()=>{
const {input1}=this.refs
alert(input1.value)
}
showData2=()=>{
const {input2}=this.refs
alert(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'))
2 回调形式的ref
拿到当前ref所在的节点 挂载实例自身
inputBlur = () =>{
alert(this.input2.value);
}
<input ref={self => this.input2 = self} onBlur={this.inputBlur} type="text" placeholder="失去焦点弹出弹出" />
关于ref回调函数的说明:
如果ref回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数null,第二次传入dom元素,
这是因为每次渲染的时候会创建一个新的函数实例,所以React清空旧的ref并且设置新的,
通过将ref回调函数定义成class的绑定函数可以避免上述问题
更新:
isRef = (self) =>{
console.log(self);
this.dian = self;
console.log("sss")
}
<input ref={this.isRef} type="text" placeholder="点击弹出" />
3 createRef创建ref容器
React.createRef 调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是专人专用的,
创建很多ref容器
MyRef = React.createRef();
class Demo extends React.Component{
//通过API,创建React的容器,相当于对于回调函数创建了一个相应的API,省略了中间环节
//但是这个容器是专人专用的,所以每一个ref都需要创建这个
MyRef = React.createRef();
MyRef1 = React.createRef();
btnOnClick = () =>{
//创建之后,将自身节点,传入current中
console.log(this.MyRef.current.value);
//alert(this.refs.dian.value);
}
inputBlur = () =>{
console.log(this);
//lert(this.refs.shiqu .value);
}
render(){
return (
<div>
<input ref={this.MyRef} type="text" placeholder="点击弹出" />
<button onClick = {this.btnOnClick}>点击</button>
<input ref={this.MyRef1} onBlur={this.inputBlur} type="text" placeholder="失去焦点弹出弹出" />
</div>
)
}
}
ReactDOM.render(<Demo />,document.getElementById("div"));
4 事件处理
React的事件是通过onXxx属性指定时间处理函数
React使用的都是自定义的时间,而不是原生的事件
React中的事件是通过事件委托方式处理的
通过event.target得到发生事件的Dom元素对象
不要过度使用ref
不写ref可以使用事件处理:
发生事件元素正好是要操作的元素
第一个就没办法使用,因为操作元素的事件在按钮身上绑定着
class Dom extends React.Component{
MyRef = React.createRef();
btnOnClick = () =>{
//创建之后,将自身节点,传入current中
console.log(this.MyRef.current.value);
}
inputBlur = (event) =>{
alert(event.target.value)
}
render(){
return (
<div>
<input ref={this.MyRef} type="text" placeholder="点击弹出" />
<button onClick = {this.btnOnClick}>点击</button>
<input onBlur={this.inputBlur} type="text" placeholder="失去焦点弹出弹出" />
</div>
)
}
}
ReactDOM.render(<Dom />,document.getElementById("div"));