react
- 声名式开发
- 可以和其他框架并存
- 组件化。
- 单向数据流,即父组件可以改变子组件的数据,但是子组件一定不能直接改变父组件的数据,必须调用父组件的方法来改变父组件的数据
- 视图层框架
- 函数式编程
Props,State与render函数
Props:指的属性,父组件通过属性的形式,向子组件传递参数
State:组件中的数据
render:渲染组件之中的内容
关系:
当组件初次创建的时候,render函数会被执行一次
当组件的state或者props发生改变的时候,render函数会被重新执行
当父组件的render函数被运行时,他的子组件的render都将被重新运行 一次
counter.js
import React,{Component,Fragment} from 'react';
import Child from './child';
class Counter extends Component{
constructor(props){
super(props);
this.handleBtnClick=this.handleBtnClick.bind(this);
this.state = {
counter:1
}
}
handleBtnClick(){
const newCounter = this.state.counter+1;
this.setState({
counter:newCounter
})
}
render(){
console.log('render');
// 当组件初次创建的时候,render函数会被执行一次
// 当state数据发生变更的时候,render函数会被重新执行
// 当props数据发生变更的时候,render函数会被重新执行
return (
<Fragment>
<button onClick={this.handleBtnClick}>增加</button>
<Child number={this.state.counter}/>
</Fragment>
)
}
}
export default Counter;
child.js
import React,{Component} from 'react';
class Child extends Component{
render(){
return (
<div>{this.props.number}</div>
)
}
}
export default Child;
如何在react中使用DOM
使用ref:一般让其等于一个函数,函数接收到的参数就是JSX标签真实对应的dom
ref 写在html标签上,获取的是dom节点
ref = {(button)=>{this.buttonElem = button}}
console.log(this.buttonElem);//获取到<button>增加</button>
ref写在组件上,获取的是组建的js实例
<Child ref = {(child)=>{this.childElem = child}} number = {this.state.counter}/>
console.log(this.childElem);
setState是异步的
ref如果要获取数据更新后的dom要在setState中传入的第二个函数中
点击打印出来了两个11 22 33…
handleBtnClick(){
const newCounter = this.state.counter+1;
console.log(this.divElem.innerHTML);//1
// setState 是异步的
this.setState({
counter:newCounter
})
console.log(this.divElem.innerHTML);//1
}
点击打印出来为12 23 34…
handleBtnClick(){
const newCounter = this.state.counter+1;
console.log(this.divElem.innerHTML);//1
// setState 是异步的
// 不接收一个对象,可以接收一个函数
this.setState(()=>{
return {
counter:newCounter
}
},()=>{
console.log(this.divElem.innerHTML);//2 第二个函数等待第一个函数数据改变完成之后在执行
})
}
import React, { Component,Fragment } from 'react';
class Counter extends Component{
constructor(props){
super(props);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.state={
counter:1
}
}
handleBtnClick(){
const newCounter = this.state.counter+1;
console.log(this.divElem.innerHTML);
// setState 是异步的
// 不接收一个对象,可以接收一个函数
this.setState(()=>{
return {
counter:newCounter
}
},()=>{
console.log(this.divElem.innerHTML)
})
}
render(){
// 当组件初次创建的时候,render函数会被执行一次
// 当state数据发生变更的时候,render函数会被重新执行
// 当props数据发生变更的时候,render函数会被重新执行
// ref 写在html标签上,获取的是dom节点
// ref写在组件上,获取的是组建的js实例
return(
<Fragment>
<button onClick = {this.handleBtnClick}>
添加
</button>
<div ref={(div)=>{this.divElem = div}}>{this.state.counter}</div>
</Fragment>
)
}
}
export default Counter;
import React, { Component,Fragment } from 'react';
class Counter extends Component{
constructor(props){
super(props);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.InputChange = this.InputChange.bind(this);
this.state={
counter:''
}
}
handleBtnClick(){
const newCounter = this.state.counter;
console.log(this.inputElem);
// setState 是异步的
// 不接收一个对象,可以接收一个函数
this.setState(()=>{
return {
counter:newCounter
}
},()=>{
console.log(this.inputElem)
})
}
InputChange(e){
this.setState({
counter:this.inputElem.value
})
}
render(){
// 当组件初次创建的时候,render函数会被执行一次
// 当state数据发生变更的时候,render函数会被重新执行
// 当props数据发生变更的时候,render函数会被重新执行
// ref 写在html标签上,获取的是dom节点
// ref写在组件上,获取的是组建的js实例
return(
<Fragment>
<input
value={this.state.counter}
onChange={this.InputChange}
ref={(input)=>{this.inputElem = input }}
/>
<button onClick = {this.handleBtnClick}>
提交
</button>
</Fragment>
)
}
}
export default Counter;