第三章
3-2 React中的响应式设计思想和事件绑定
案例:通过点击提交,将input框里的内容追加到列表里;
·常规 Javascript 中,我们一般是通过操作 dom 来实现此功能:
$("#root").on('click','.submit',function(){
var inputValue = $("input").val();
$("ul").append("<li>"+inputValue+"</li>");
});
·而在 react 中,我们无须关注 dom 的相关操作,而是通过对数据进行操作,react 会自动感知到数据的变化,从而自动完成对页面的渲染;
·即 react 是一个响应式的框架;
1.TodoList.js
我们需要存储两个数据,一个是 input 框里的数据,一个是列表里的每一项;(即inputValue,list)
import React, { Component, Fragment } from 'react';
class TodoList extends Component {
//当我们调用TodoList时,constructor(构造函数)会优先于其它任何函数自动最先被的行
constructor(props){
super(props);//调用父类的构造函数一次
this.state = {
inputValue: 'hello world',
list: []
}
}
render (){
return(
<div>
<input />
<button>提交</button>
</div>
<ul>
<li>hello</li>
</ul>
)
}
}
export default TodoList;
1).数据绑定
<input /> 里的数据存放在 inputVlaue ,因而需要将 input 里的数据和状态里的 inputValue 作一个绑定:
<input value={this.state.inputValue} />
这里 input 显示什么是由 this.state.inputValue 决定的,在这里 this.state.inputValue 是一个变量,如果需要使用变量,JSX语法中需要添加一对 {} ;
2).事件绑定
此时的代码运行,会发现 input 框里自动显示 "hello world" ,但无论我们在框里输入什么,input 始终不变化;
原因就是 input 显示什么由 state 里的 inputValue 决定的,inputValue 不发生改变,input 也不会有变化;
因而我们需要绑定一个监听事件,通过监听事件将监听到的内容传给 inputValue ,从而使 input 发生变化:
<input
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
注:
在以往代码中我们也可以直接在 HTML 标签里绑定 onchange 事件,但 JSX 语法中 onChange 的 C 必须大写;
handleInputChange(e) {
const value = e.target.value;
this.state.inputValue = value;
}
e 是一个事件对象,会有 target 属性,这里的 target 指的就是 input 框的 dom 节点;
ps:可以通过 console.log(e.target); 在控制台查看输出;
this 的指向问题:
添加如上的监听事件方法,会有报错,可以在方法中添加 console.log(this); 代码,控制台输出是 undefined ,this 指向有问题;
在 constructor 构造函数中添加相应代码:
constructor(props){
super(props);
this.state = {
inputValue: 'hello world',
list: []
};
this.handleInputChange = this.handleInputChange.bind(this);
}
如何改变 state 里的状态:
如上代码虽然可以改变 state 里的 inputValue 的值,但是仍然无法重新渲染页面,从而使 input 框的里的内容发生改变;
在 React 中,如果想改变 state 里的状态,不能通过 this.state.inputValue 引用的方式取改变它里面的值;
React 提供了一个 setState 方法供我们调用,去改变 state 里的数据;
handleInputChange(e) {
const value = e.target.value;
this.setState(() => {
return{
inputValue : value
}
});
}
2.TodoList.js完整代码:
import React, { Component, Fragment } from 'react';
class TodoList extends Component {
constructor(props){
super(props);
this.state = {
inputValue: 'hello world',
list: []
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(e) {
const value = e.target.value;
this.setState(() => {
return{
inputValue : value
}
});
}
render (){
return(
<div>
<input
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
<button>提交</button>
</div>
<ul>
<li>hello</li>
</ul>
)
}
}
export default TodoList;