index.js中ReactDOM.render(<App />, document.getElementById('root'));
也就是使用了app.js中class App的render()返回值
render中只允许存在一个顶级标签,就像vue中template中最外层只能有一个标签一样。
添加响应函数:
<button onClick={testClick}>
我是一个按钮
</button>
纯html中写的οnclick="",此处赋值是一个字符串
react中赋值是一个对象,这里的testClick可以写在render(){}函数里面,也可以写在class App{}外面,因为没有this.调用
如果是class App{}里面的函数,则应该
<button onClick={this.testClick}>
我是一个按钮
</button>
如果想一个元素绑定多个事件
<button onClick={event=>{this.testClick2(); testClick3(); testClick()}}>
我是一个按钮
</button>
其实也是一个函数,只不过函数写在onClick的实现中了,然后在实现函数中调用3个函数
变量的使用:
constructor(props){
super(props);
this.state={
val1:'haha',
val2:'biubiubiu',
}
this.val = 'value 1'
this.Nothing = this.Nothing.bind(this);
console.log('app constructor')
}
可以在state中定义,也可以自定义,如果该变量需要渲染刷新则定义到state中,如果只是存放数据,就没必要放在state中浪费了。
也可以写作
constructor(props){
super(props);
console.log('app constructor')
}
state = {
val1:'walala',
val2:'buibuibui',
};
val = 'value first'
render() {
return (
<div>
<button>
我是一个按钮
</button>
<p>{this.state.val1}</p>
</div>
)
}
修改state中的数据可以使用this.state.val1='change',也可以使用this.setState({val1:'val1'})
直接用=赋值,不会影响页面,只是赋值而已,但是state中存放的一般是需要渲染刷新的数据,所以最好使用setState,因为setState中会默认触发render函数。如果觉得没必要使用setState,那这个变量也没必要放到state中。setState的第二个参数是数据被修改,render被执行后的回调,可选参数。setState是异步执行的,所以立刻console.log打印不一定能获取到最新设置的值,而是update时的值,update之前的所有赋值会融合,得到最新的数据,就像assign
var a = {'name':'Tom', age:18}
var b = {'name':'Jim', gender:'male'}
var c = Object.assign({}, a, b)
console.log(c)
输出{name: "Jim", age: 18, gender: "male"}
setState是异步的,要想setState获取到最新数据,可以使用以下方式
1.
changeState(){
this.setState({
value:true,
}()=>{
console.log('value changed', this.state.value)
})
}
setState的第二个参数是回调函数, setState执行完并页面渲染完之后再执行
2.
async changeStete(){
await this.setState({value:true})
console.log("await value chagned", this.state.value)
}
this的使用:
react中直接使用this.state.val1='1111',或者setState可能会报错
<button onClick={this.testClick2}>
我是一个按钮
</button>
报错:Cannot read property 'state' of undefined
这是因为testClick2已经作为一个对象赋值了,当他执行的时候,函数虽然还是那个函数,但是对象已经不是那个对象了。这条路线下的this已经是undefined了,不信可以console.log(this)看看结果。要想正确使用,可以在这么做:
<button onClick={event=>{this.testClick2()}}>
我是一个按钮
</button>
原理是,直接写响应函数,在响应函数中调用触发函数
或者执行bind(this)
constructor(props){
super(props);
this.testClick2 = this.testClick2.bind(this);
console.log('app constructor')
}
附index.js乱七八糟的代码,虽然乱起八糟,主要是验证语法
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor(props){
super(props);
this.Nothing = this.Nothing.bind(this);
console.log('app constructor')
}
state = {
val1:'walala',
val2:'buibuibui',
};
val = 'value first'
render() {
return (
<div>
<div id="inApp">
</div>
<div id="inApp2">
</div>
<button onClick={event=>{this.testClick2(); testClick3(); testClick()}}>
我是一个按钮
</button>
<p>{this.state.val1}</p>
</div>
)
function testClick(){
console.log('testClick button clicked')
}
}
testClick2(){
var a=new Date()
var b = a.toString();
//this.setState({val1:b})
this.state.val1 = b
this.val = b
Nothing2 = Nothing2.bind(this);//不能写成this.Nothing2
const element=<this.Nothing a="哈鲁根"/>;
ReactDOM.render(element, document.getElementById('inApp'))
function Nothing2(props){
return <p>what no thing {props.a}-{this.state.val2}-{this.val}</p>
}
const element2=<Nothing2 a="没有了"/>;
ReactDOM.render(element2, document.getElementById('inApp2'))
}
Nothing(props){
return (
<p>what no thing {props.a}-{this.state.val1}</p>
)
}
componentDidMount(){
setInterval(()=>{
this.updateValue()
}, 1000)
}
updateValue(){
var a = new Date()
var b = a.toString()
this.setState({val1:b})
}
}
function testClick3(){
console.log(new Date())
}
export default App;