本文主要讲解react组件中如何定义方法,调用方法,获取数据,改变数据,方法传值,调用方法时改变this指向。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
}
runFun() {
console.log("runfun");
}
render(){
return(
<div>
<button onClick={this.runFun()}>runFun</button>
</div>
)
}
}
export default Demo1;
这个地方的意图是点击按钮打印’runfun’,看下实际效果:
可以看到,没有点击,但是方法runFun已经调用了,这个地方的原因是runFun方法后面加了括号,加上括号之后就表示要调用这个方法,所以更改如下:
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
}
runFun() {
console.log("runfun");
}
render(){
return(
<div>
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
去掉runFun后面的括号后得到了预期的结果:每点击一次按钮执行一次runFun方法。
现在想要点击按钮获取state中的值,这个改如何实现?
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值"
}
}
runFun() {
console.log(this.state.msg);
}
render(){
return(
<div>
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
看到报了一个这样的错误,TypeError: Cannot read property 'state' of undefined
,报这个错误的原因是this指向
的问题,this指向可以参考:js之旅(七)js中this
在react中,可以用三种方式改变this指向
可以在调用函数的时候借助于bind函数来改变被调用方法中的this指向。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值"
}
}
runFun() {
console.log(this.state.msg);
}
render(){
return(
<div>
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.runFun.bind(this)}>runFun</button>
</div>
)
}
}
可以在构造函数中,一开始就改变this的指向。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值"
}
this.runFun = this.runFun.bind(this);
}
runFun() {
console.log(this.state.msg);
}
render(){
return(
<div>
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
这样也可以得到想要的效果。
可以将被调用的函数定义成箭头函数,这样就不用关心this指向的问题。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值"
}
}
runFun = () => {
console.log(this.state.msg);
}
render(){
return(
<div>
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
将数据放到state中,怎样去改变state中的值呢?在react中,可以调用setState
方法来改变state的值当state值被改变后,会重新执行render方法,渲染数据。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
test: "test",
msg: "state中的值"
}
}
changeData = () => {
this.setState({
msg: "改变后state中的值"
})
}
render(){
return(
<div>
<div>{this.state.test}</div>
<br />
<br />
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.changeData}>runFun</button>
</div>
)
}
}
export default Demo1;
可以看到,调用setState
方法后,重新执行render方法
,重新渲染页面
,而且,setState方法仅仅改变被修改的值,对state对象中的其它值没有影响
。
下面有个疑问?多次改变state中的值,render方法调用几次?
//情景一
this.setState({
msg: {
msg: "改变后state中的值",
test: "改变后state中的值1"
}
});
//情景二
this.setState({
msg: "改变后state中的值",
test: "改变后state中的值1"
});
//情景三
this.setState({
msg: "改变后state中的值",
});
this.setState({
test: "改变后state中的值1"
});
上面这三种情景都会调用两次render方法。是不是可以得出结论:改变几个值就会调用几次render方法?这是错误的!!!!
,为什么这样说?先举一个反例:
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值",
msg1: "msgs",
msg2: "msg2",
msg3: "msg3"
}
}
runFun = () => {
this.setState({
msg: "改变后state中的值",
});
this.setState({
msg1: "改变后msgs",
});
this.setState({
msg2: "改变后msg2",
});
this.setState({
msg3: "改变后msg3"
});
}
render(){
console.log("render");
return(
<div>
<div>{this.state.msg}</div>
<br />
<div>{this.state.msg1}</div>
<br />
<div>{this.state.msg2}</div>
<br />
<div>{this.state.msg3}</div>
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
发现改变了四个值,render方法任然是调用了2次。
看一下官方说明:
setState之后发生的事情
因为 React 在 Dev mode(开发模式) 下会刻意执行两次渲染,以防止组件内有什么 side effect 引起 bug,提前预防。
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值",
msg1: "msgs",
msg2: "msg2",
msg3: "msg3"
}
}
runFun = () => {
this.setState({
msg: "改变后state中的值",
});
this.setState({
msg1: "改变后msgs",
});
this.setState({
msg2: "改变后msg2",
});
this.state.msg3 = "test msg3"
}
render(){
console.log("render");
return(
<div>
<div>{this.state.msg}</div>
<br />
<div>{this.state.msg1}</div>
<br />
<div>{this.state.msg2}</div>
<br />
<div>{this.state.msg3}</div>
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
实际测过发现是可以的,为什么网上都说不行?看下面的代码:
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值",
msg1: "msgs",
msg2: "msg2",
msg3: "msg3"
}
}
runFun = () => {
this.setState({
msg: "改变后state中的值",
});
this.setState({
msg1: "改变后msgs",
});
this.setState({
msg2: "改变后msg2",
});
this.setState({
msg3: "改变后msg3",
});
this.state.msg3 = "test msg3"
}
render(){
console.log("render");
return(
<div>
<div>{this.state.msg}</div>
<br />
<div>{this.state.msg1}</div>
<br />
<div>{this.state.msg2}</div>
<br />
<div>{this.state.msg3}</div>
<br />
<button onClick={this.runFun}>runFun</button>
</div>
)
}
}
export default Demo1;
发现msg3并没有使用直接赋值的值,而是用了setState中的值。
这个地方可以这样理解:
借助于bind方法,可以实现给方法传值:
import React from 'react';
class Demo1 extends React.Component {
constructor(props){
super(props);
this.state = {
msg: "state中的值"
}
}
changeData(msg){
this.setState({
msg: msg
});
}
render(){
console.log("render");
return(
<div>
<div>{this.state.msg}</div>
<br />
<br />
<button onClick={this.changeData.bind(this, "改变后msg的值")}>runFun</button>
</div>
)
}
}
export default Demo1;