响应式设计思想和事件绑定
React与以往框架jquery不同,它是一个响应式的框架,react在做编程的时候,强调的是操作数据而不是dom,一旦数据发生改变,React会自动感知到数据的变化,自动帮你生成dom.
所以在写react的时候,我们再也不用关注dom的操作了,我们只需关注数据层的操组即可。
拿todolist来说,需要多少数据呢?
只需要2个,一个存储input里面的值,一个存储list列表
react事件和与原生js一样,只不过第二个单词的字母要大写,如原生绑定onclick,onchange到react就变成onClick,onChange, 即事件名称的首字母要大写
onClick
onChange
onKeyDown
: 这里的e有2个特殊的属性keyCode
(等于13时为enter,常用于回车搜素)target.value
(input的value值)
react如何定义数据
TodoList是一个组件,或者说是一个类
对于类来说,每一个类中都有一个constructor
的函数,当我们在创建类的实例的时候, constructor
是第一个被执行的函数,所以我们可以把数据的初始化工作放在constructor
里面。 constructor
的写法比较固定:
constructor(props){
//super指的是父类,这里也就是React.Component,先调用一次父类的构造函数
super(props);
//state存储组件的数据
this.state={
inputValue:"",
list:[]
}
}
访问组件数据
注意{}
表示的是一个js表达式
this.state.inputValue
this.state.list
改变组件数据
必须调用setState
方法 且不能在原值上更改 这意味着你得先去拷贝一份state 然后在备份数据上修改 最后把备份state返回回去
这一系列操作太过于繁琐,react18已经把immutable集成进去了,你只要修改任何state里的属性,都会给你返回一个新的state
//同步
this.setState({
inputValue : "",
list:[...this.state.list,this.state.inputValue] //先拷贝一份,然后用后面的新值去覆盖
})
//异步1
this.setState(()=>({
inputValue : "",
}))
//异步2
this.setState((prevState)=>({
inputValue:"",
list:[...prevState.list,prevState.inputValue]
}))
react定义方法
import React from 'react';
import { Component, Fragment } from 'react' //Fragment占位符,大写字母开头,它本质是一个组件
class TodoList extends Component{
constructor(props){
super(props)
this.state={
inputValue:"",
list:[]
}
}
render(){
return (
<Fragment>
<input
type="text"
value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}
//通过绑定组件的this来改变函数的this指向,实际改变作用域
//如果这里不绑定this(this.handleInputChange),通过console.log(this)你将得到undifined
/> <button>提交</button>
<ul>
<li>apple</li>
<li>pear</li>
</ul>
</Fragment>
)
}
handleInputChange(e){ //handleInputChange 可以接收一个event参数,
this.setState({
inputValue:e.target.value //e.target是一个dom元素
// list:[list...,e.target.value]
})
}
}
export default TodoList;