组件的三大核心属性
state(状态)
- state是组件对象最重要的属性,值是对象,可以包含多个key-value的组合。
- 组件被称为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)
- 组件中的render方法中的this为组件实例对象
- 组件自定义的方法中this为undefined的解决方法:
a. 强制绑定this:通过函数对象的bind()
constructor(props){
super(props)
//初始化状态
this.state = {isHot:true}
//解决changeWeather中this指向问题
this.changeWeather = this.changeWeather.bind(this)
}
b.箭头函数
changeWeather = ()=>{
const isHost = this.state.isHost
this.setState({isHost: !isHost})
}
- 状态数据:不能直接修改或更新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>简化版State</title>
</head>
<body>
<!--准备好一个容器-->
<div id="test"></div>
<!--引入react核心库-->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<!--引入react-dom,用于支持react操作DOM-->
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel,用于将jsx转为js-->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
//1、创建主机
class Weather extends React.Component{
//初始化状态
state = {isHost:false}
render(){
const {isHost} = this.state
return <h1 onClick={this.changeWeather}>今天天气很 {isHost ? '炎热': '凉爽'}</h1>
}
//自定义方法--要用赋值语句的形式+箭头函数
changeWeather = ()=>{
const isHost = this.state.isHost
this.setState({isHost: !isHost})
}
}
//2、渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'))
</script>
</body>
</html>
查看运行结果:
点击凉爽触发改变状态(state)为炎热
props
- 每个组件对象都会有props属性。
- 组件标签的所有属性都保存在props中。
批量传递标签属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>props</title>
</head>
<body>
<!--准备好一个容器-->
<div id="test"></div>
<!--引入react核心库-->
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<!--引入react-dom,用于支持react操作DOM-->
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel,用于将jsx转为js-->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
//1、创建组件
class Person extends React.Component{
render(){
const {name,age,sex}=this.props
return(
<ul>
<li>姓名:{name}</li>
<li>性别:{age}</li>
<li>年龄:{sex}</li>
</ul>
)
}
}
//2、渲染组件到页面
ReactDOM.render(<Person name="肖战" age="28" sex="男"/>,document.getElementById('test'))
</script>
</body>
</html>
查看运行结果:
props对标签属性进行类型、必要性限制
<!--引入prop-type,用于对组件标签属性进行限制-->
<script src="https://cdn.bootcdn.net/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
Person.propTtype={
name:PropTypes.string.isRequired,//限制name必传,且为字符串
sex:PropTypes.string,//限制sex为字符串
age:PropTypes.number,//限制age为数值
}
//指定默认标签属性
Person.defaultProps={
sex:'女',//sex默认值为女
age:'18',//age默认值为18
}
构造器是否接收props,是否传递给super,取决于是否希望在构造器中通过this访问props
函数组件使用props
function Person(props){
const {name,age,sex} = props
return(
<ul>
<li>姓名:{name}</li>
<li>年龄:{age+1}</li>
<li>性别:{sex}</li>
</ul>
)
}
refs
- 组件内的标签可以定义ref来表示自己。
字符串形式的refs(不推荐:string类型的refs存在一些效率问题,已过时)
<script type="text/babel">
//1、创建组件
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>
)
}
}
//2、渲染组件到页面
ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>
查看运行结果:
回调形式的ref:
react关于refs的官方文档:https://react.docschina.org/docs/refs-and-the-dom.html
- 如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM
元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成
class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
//展示左侧输入框的数据
showData=()=>{
const {input1} = this
alert(input1.value)
}
//展示右侧输入框的数据
showData2 = ()=>{
const {input2} = this
alert(input2.value)
}
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>
)
}
}
//2、渲染组件到页面
ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>
createRef
React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的。
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
myRef = React.createRef()
myRef2 = React.createRef()
//展示左侧输入框的数据
showData=()=>{
alert(this.myRef.current.value);
}
//展示右侧输入框的数据
showData2 = ()=>{
alert(this.myRef2.current.value);
}
render(){
return(
<div>
<input ref={this.myRef} type="text" placeholder="点击按钮显示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
</div>
)
}
}
//2、渲染组件到页面
ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
</script>