<>1. react数据异步更新
定义一个类组件模板:
class MyCom extends React.Component{}
设置state状态数据:
state = { name: "张三" }
render()渲染函数:
render(){ return <button onClick={this.change}>{this.state.name}</button> }
过程:this打点调用自定义函数change绑定click事件,返回一个button按钮,通过this.state打点调用自定义属性name。
在ReactDOM.render()中调用类组件模板:
ReactDOM.render( <MyCom/>, document.getElementById('example') )
现要修改button按钮的内容,点击按钮数据会更新,张三变成李四。通过箭头函数定义自定义函数change:
change = ()=>{ this.setState({ name: "李四" }) //
注意:this.setState数据更新属于异步更新,此处打印是更新前的值 console.log(1, this.state.name); // 张三 }
* 注意:this.setState数据更新 属于 异步更新,此处打印是更新前的值
<>2.1 在生命周期钩子中更新数据
* 生命周期钩子更新后调用数据,就会得到更新后的数据,即异步更新数据 componentDidUpdate = (prevProps,
prevState) => { console.log(2, prevState.name, this.state.name); // 张三 李四 }
<>2.2 使用this.setState的异步回调更新数据
* this.setState() 的第二个参数是可选的 回调,是异步更新完成时的回调(与 小程序的this.setData() 相同,也是异步更新回调)
this.setState({ name: "李四" }, ()=>{ console.log(3, this.state.name); // 李四 })
<>补充:vue的异步更新回调
* 在vue异步更新中 this.name=“李四”; this.$nextTick(()=>{})是vue中的异步更新回调
* this. n e x t T i c k ( ( ) = > ) 将 回 调 函 数 中 的 操 作 放 到 下 一 次 D O M 更 新 之 后
执 行 , 类 似 全 局 方 法 v u e . n e x t T i c k , 只 不 过 t h i s . nextTick(()=>{ })
将回调函数中的操作放到下一次DOM更新之后执行,类似全局方法vue.nextTick,只不过 this.nextTick(()=>)将回调函数中的操作放到下一次
DOM更新之后执行,类似全局方法vue.nextTick,只不过this.nextTick 只作用于调用它的实例 <template> <button ref=
"ctyBtn" @click="clickHandle">{{content}}</button> </template> <script> export
default { data () { return { content: '初始值' } }, methods: { clickHandle () {
this.content = '改变了的值' // 这时候直接打印的话,由于dom元素还没更新 // 因此打印出来的还是未改变之前的值 this.
$nextTick(() => { // dom元素更新后执行,因此这里能正确打印更改之后的值 console.log('1 ' + this.$refs.
ctyBtn.innerText) // 改变了的值 }) console.log('2 ' + this.$refs.ctyBtn.innerText)
// 初始值 } } } </script>
<>2. react获取DOM元素的三种方式
<>2.1 标签设置ref属性,通过 this.refs 调用
* 此方式属于老版本语法,将要废除 <div ref="d1">1</div> <button
onClick={this.getDOM}>找div</button>
在自定义函数中,通过 this.refs 调用 d1的内容
getDOM = ()=>{ console.log(this.refs.d1.innerText); // 找d1 }
<>2.2 在构造器中创建ref全局变量,在标签中通过ref属性动态绑定这个全局变量,通过全局变量的current字段调用
<div ref={this.d2}>2</div>
* 在构造器中创建ref全局变量,把d2的数据放入 React的createRef容器 中 constructor(props){
super(props); this.d2 = React.createRef() }
* 通过全局变量的 current字段 调用d2的内容 console.log(this.d2.current.innerText); // 找d2
<>2.3 在标签中通过ref属性动态绑定函数,在函数中定义全局变量赋值,通过全局变量调用
<div ref={el => this.d3 = el }>3</div> // <div ref={(el) => { return this.d3 =
el}}>3</div>
* 在函数中通过全局变量调用d3的内容 console.log(this.d3.innerText); // 找d3
<>注意事项:
定义一个函数式组件(子组件):
function Child1(){ return <div>Child1</div> }
定义一个类组件(子组件):
class Child2 extends React.Component{ state = { name: "军人" } change = ()=>{
this.setState({ name: "士兵" },()=>{ console.log("修改后数据:", this.state.name); }) }
render(){ return <div onClick={this.change}>Child2</div> } }
<>1, 在父组件中用ref获取子组件对象, 必须保证子组件是类组件, 函数式组件获取结果是undefined
* 使用第一种获取DOM的方式,在渲染函数render()中通过ref属性,渲染子组件 <Child1 ref="child1"/> <Child2
ref="child2"/>
* 在函数中通过 this.refs 调用 console.log(this.refs.child1); // undefined
console.log(this.refs.child2.state.name);
* 函数式组件,不能设置ref属性,会报错,查找结果是undefined
<>2, 父组件使用ref获取子组件对象后, 可以对子组件状态数据和函数执行调用和修改
console.log(this.refs.child1); // undefined
console.log(this.refs.child2.state.name);
* 函数式组件,不能设置ref属性,会报错,查找结果是undefined