state
1.类中方法this的指向
- constructor和render里的this指向类组件的实例对象
- 在类组件内部定义的普通函数,作为onClick的回调,不是通过实例调用的,是直接调用,并且类组件内部默认开启了局部严格模式,所以this指向undefind
2.将类组件内部定义的函数内部this指向类组件的实例对象
- 利用箭头函数
- 在构造器中通过bind改变函数this指向,赋值于实例对象的新定义的方法
3.初始化状态写法
- 初始化状态写在构造器中 this.state = {}
- 如果类组件省略构造器了,初始化状态也可以直接以 state= {}写在组件内
4.读取状态
- this.state.状态名
5.更改状态
- this.setState()
- 不能直接修改或更新
以上知识点和详解可以参照下面代码和注释
<head>
<div id="test"></div>
</head>
//引入一些react核心库和babel
<script type="text/javascript" src="..."></script>
<script type="text/babel">
//1.创建一个类式组件
class Demo extends React.Component {
constructor(props){
super(props)
this.state = { // 初始化状态
isHappy:true,
isWeather:true
}
this.changeWeather= this.changeWeather.bind(this)
//实例上没有changeWeather方法,但是可以通过原型对象上访问到,然后通过bind改变了函数的this,并赋值给了实例对象上的changeWeather
}
// 如果类组件省略构造器了,初始化状态也可以直接以 state= {}写在组件内
// state = {
// isHappy:true,
// isWeather:true
//}
click = () => { // 利用箭头函数
this.setState({
isHappy:!isHappy
})
}
changeWeather(){
//changeWeather放到了Demo的原型对象上,供实例使用
//changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部严格模式,所以changeWeather的this指向undefind
this.setState({
isWeather:!isWeather
})
}
render() {
const {isHappy,isWeather} = this.state
return (
<div>
<h2 onClick={this.click}>今天我很{ isHappy ? '开心' : '伤心'}</h2>
<h2 onClick={this.changeWeather}>今天天气{ isWeather ? '很好' : '很坏'}</h2>
</div>
)
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Demo/> ,document.getElementById('test'))
</ script>
props
1.props一般用于父组件向子组件传值
- 父组件通过标签属性把值传给子组件
- 子组件可以通过this.props.属性名去取
2.子组件需要引入prop-types插件来定义props
- 定义props传入值的类型
- 定义props传入值是否必传
- 定义props传入值的默认格式
3.读取props
- this.props.属性名
4.更改传入的props值
- 在子组件内不能通过 “ this.props.属性名= ”的方式直接修改
- 需要在父组件取定义修改方法,传给子组件,子组件调用修改方法取修改值
以上知识点和详解可以参照下面代码和注释
<head>
<div id="test"></div>
</head>
//引入一些react核心库和babel
<script type="text/javascript" src="..."></script>
//引入prop-types插件
<script type="text/javascript" src="..."></script>
<script type="text/babel">
//父组件
class Info extends React.Component {
state = {
infomation:[
{name:'张三',sex:'男'},
{name:'李四',sex:'女'}
]
}
render() {
const {infomation} = this.state
return (
<div>
<Person info={infomation}></Person>
</div?
)
}
}
//子组件
class Person extends React.Component {
static propTypes = { //定义props的类型,isRequired表示是否必传
info: PropTypes.Array.isRequired
}
static defaultProps = { //定义info的默认展示数据
info:[{name:'xxx',sex:'xxx'}]
}
render() {
const {info} = this.props
return (
<ul>
{info.map(item => {
return <li>{name}:{sex}</li>
})
}
</ul>
)
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Person/> ,document.getElementById('test'))
</ script>
refs
1.定义
- 组件内的标签可以定义ref来表示自己,获取其节点数据
2.ref的类型
- 字符串ref; 例如:"ref=“input1"” (官方不推荐使用,如果使用量大会存在效率问题)
- 回调函数ref;例如:“ref={c => this.input2= c}”(在更新过程中会执行两次,第一次传入参数是null,第二次会传入参数DOM元素,但无关紧要,推荐使用)
- createRef
3.避免过度得使用ref
- 发生事件的元素正是你要操作的元素,可以使用onClick合成事件,通过event.target去获取操作元素的节点信息
(以上知识点和详解可以参照下面代码和注释)
字符串ref案例组件
<head>
<div id="test"></div>
</head>
//引入一些react核心库和babel
<script type="text/javascript" src="..."></script>
<script type="text/babel">
//字符串ref案例组件
class Demo extends React.Component {
click = () => {
console.log(this.refs.input1) //真实DOM的input节点
const {input1} = this.refs
alert(input1.value) //弹出input输入框的内容
}
render() {
return(
<div>
<input ref="input1" type="text" placeholder="点击按钮提示数据">
<button onClick={this.click}>点击按钮显示左侧数据</button>
</div>
)
}
}
//渲染虚拟DOM到页面
ReactDOM.render(<Demo/> ,document.getElementById('test'))
</ script>
回调函数ref案例组件
//回调函数ref案例组件
...
class Demo1 extends React.Component {
showData= () => {
const {input2} = this
alert(input2.value) //弹出input输入框的内容
}
saveInput = (c)=> {
this.input3 = c
console.log(this.input3,c) //真实DOM的input节点
alert(this.input3.value) //弹出input输入框的内容
}
render() {
return(
<div>
{/*1.ref={c => {console.log(c)}} 此时打印的c就是input节点,然后把节点赋值给this上新属性input2,故可以通过this.input2获取其DOM节点;
2.每次渲染时会创建一个新的函数实例,所以React清空了旧的ref并设置成新的,所以此方法会有在更新过程中会执行两次,第一次传入参数是null,第二次会传入参数DOM元素的问题;
3.但是上面问题无关紧要,推荐使用*/}
<input ref={c => this.input2= c} onBlur={this.showData} type="text" placeholder="失去焦点提示数据">
{/*通过将ref的回调函数定义成class的绑定函数的方式来避免上面的问题*/}
<input ref={this.saveInput} onBlur={this.showData} type="text" placeholder="失去焦点提示数据">
</div>
)
}
}
//渲染虚拟DOM到页面
ReactDOM.render(<Demo1/> ,document.getElementById('test'))
createRef案例组件
//createRef案例组件
...
class Demo2 extends React.Component {
//React.createRef()调用后可以返回一个容器,该容器用来存储ref所标识的节点
//该容器是专用的,每个节点需要各自的容器,如果过多的节点使用fef,会比较繁琐。但是官方推荐使用
myRef = React.createRef()
myRef2 = React.createRef()
click = () => {
console.log(this.myRef.current) //真实DOM的input节点
const {current} = this.myRef
alert(current.value) //弹出input输入框的内容
}
showData= () => {
const {current} = this.myRef2
alert(current.value) //弹出input输入框的内容
}
render() {
return(
<div>
<input ref={this.myRef} type="text" placeholder="点击按钮提示数据">
<button onClick={this.click}>点击按钮显示左侧数据</button>
<input ref={this.myRef2} onBlur={this.showData} type="text" placeholder="失去焦点提示数据">
</div>
)
}
}
//渲染虚拟DOM到页面
ReactDOM.render(<Demo2/> ,document.getElementById('test'))