react 学习笔记day-02
处理事件
使用React元素处理事件与处理DOM元素上的事件非常相似,有一些语法差异
React事件使用camelCase命名,而不是小写
使用JSX,将传递函数作为事件处理函数,而不是字符串
HTML:
<button onclick = "activateLasers()">Activate Lasers</button>
React:
<button onClick={activateLasers}>Activate Lasers</button>
另外一个区别是,无法返回false
以防React
的默认行为,必须使用preventDefault
明确调用。
HTML:
<a href="#" onclick="conslog.log('The link was clicked'); return false">Click me</a>
React:
1 | function ActionLink(){ |
使用React,通常不需要调用addEventListener添加侦听器到DOM元素后创建,相反,只需在元素初始呈现时提供侦听器
Toggle组件
1 | class Toggle extends React.Component{ |
如果引用一个没有()
后面的方法,比如onClick={this.handleClick}
你应该绑定那个方法
1 | class LoggingButton extends React.component{ |
将参数传递给事件处理程序
在循环内部,通常需要将一个额外的参数传递给事件处理程序。下例,id
是行ID
<button onClick={(e) => this.deleteRow(id,e)}>Delete Row</button>
<button onClcik={this.deleteRow.bind(this,id)}>Delete Row</button>
e
代表React事件的参数都将作为ID之后的第二个参数传递,使用箭头函数,我们必须明确传递它,但是bind任何更多的参数都会自动转发
有条件的渲染
React中,可以创建封装所需行为的独特组件,可以仅渲染其中的一部分,具体取决于应用程序的状态
React中的条件呈现与条件跟js的工作方式相同,使用js的if运算符,或者是条件运算符创建表示当前状态的元素,并让React更新UI来匹配它们
1 | function UserGreeting(props){ |
元素变量
可以使用变量来存储元素,有条件地渲染组件的一部分,而其余输出不会更改
代表注销和登录按钮的新组件
1 | function LoginButton(props){ |
创建有状态的组件LoginControl
,呈现<LoginButton/>
或<LogoutButton/>
根据其当前状态,它也会呈现一个<Greeting/>
1 | class LoginControl extends React.Component{ |
内联使用逻辑&&运算符
包裹在花括号中嵌入JSX的任何表达式中
1 | function Mailbox(props){ |
与条件元素内联使用if-else
eg1:
1 | render(){ |
eg2:
1 | render(){ |
防止组件呈现
组件可以隐藏自身,null
1 | function WarningBanner(props){ |
null
从组件的render
方法返回不会影响声明周期方法的触发
列表和键
js中转换列表,map
函数来获取numbers并将其值加倍
1 | const numbers = [1,2,3,4,5]; |
而在React中,将数组转换为元素列表几乎完全一样
渲染多个组件
可以构建元素集合,并使用大括号将其包含在JSX中 {}
numbers使用js map函数遍历数组,li
为每个项目返回一个元素,最后将得到的元素数组分配给listItems
1 | const numbers = [1,2,3,4,5]; |
再将整个listItems
数组包含在一个ul
元素中,并将其呈现给DOM
1 | ReactDOM.render( |
基本列表组件
组件中渲染列表
可以将前面的例子重构为一个组件,该组件接受一个数组numbers并输出一个无序的元素列表
1 | function NumberList(props){ |
运行这段代码时,会给你一个警告,即应该为列表项提供一个密钥。“键”是在创建元素列表时需要包含的特殊字符串属性
1 | function NumberList(props){ |
键
可以帮助React识别哪些项目已经更改,添加,删除。键应该赋予数组内稳定的元素
1 | const numbers - [1,2,3,4,5]; |
选择id作为标志关键字比较多
1 | const todoItems = todo.map( |
如果没有稳定id,可以使用索引
1 | const todoItems = todos.map((todo,index) => |
如果项目的顺序会改变的话,则不建议使用索引,这可能会对性能造成负面影响,并可能带来组件状态问题。
用键提取组件
提取listItem组件,保留数组中的元素而不是本身li元素
1 | function ListItem(props){ |
key在兄弟姐妹中必须是唯一的
在我们生成两个不同数组的时候,我们可以用相同的键
1 | function Blog(props){ |
在JSX嵌入map()
1 | function NumberList(props){ |
这样嵌套使用有可能提高了可读性,但是如果map嵌套起来太复杂的话就可以考虑提取组件出来
形式forms
受控组件
表单元素(Input/textarea/select)通常保持自己的状态并根据用户输入更新,在React中,可变状态通常保存在组件的状态属性中,并且更新只能使用setState()
可以通过使React状态成为单一真相源来结合着两者,然后呈现表单的React组件也控制后续用户输入中以该表单发生的事情。输入表单元素的值由React以这种方式控制,叫做‘受控组件’
1 | class NameForm extends React.Component{ |
由于value属性设置在表单元素上,因此显示的值将始终为this.state.value,使React状态成为真值的来源,由于handleChange每次击键时都会运行以更新React状态,因此显示的值将随用户键入而更新
对于受控组件,每个状态变异都会有一个关联的处理函数,这使修改或验证用户输入变得非常简单,例如我们想强制全部大写来编写名称
1 | handleChange(event){ |
textarea标签
HTML中:
<textarea>textarea</textarea>
React中,value
属性代表textarea的值
1 | class EssayForm extends React.Component{ |
选择标签
HTML中:
1 | <select> |
React中:
1 | class FlavorForm extends React.Component{ |
总的来说,<input type="text">
,<textarea>
和<select>
所有的工作过程都比较相似,都可以接受value
,可以通过它实现控制组件的属性
注意:
可以将数组传递给value属性,从而在select标签中选择多个选项
<select multiple = {true} value={[‘B’,’C’]}>
文件输入标签
它的值是只读的,所以它是React中不受控制的组件
HTML:
<input type = "file>"
处理多个输入
当需要处理多个受控input元素时,可以name为每个元素添加一个属性,并让成处理函数根据值来选择要执行的操作event.target.name
1 | class Reservation extends React.Component{ |
其中
1 | this.setState({ |
相当于下面的这个es5代码:
1 | var pratialState = {}; |
受控组件的替代品
使用受控组件有时会非常乏味,因为您需要为数据可以改变的每种方式编写一个事件处理程序,并通过React组件管理所有输入状态。当您将预先存在的代码库转换为React或将React应用程序与非React库集成时,这会变得特别烦人。在这些情况下,您可能需要检查不受控制的组件,这是实现输入表单的另一种技术。
九、提升状态Lifting State Up
通常几个组件需要放映相同的变化数据,建议将共享状态提升至最接受的共同祖先
温度计算器,用于计算在给定温度下水是否沸腾
1 | funtion BoilingVerdict(props){ |
华氏 摄氏同时转换判断是否水沸腾(props/state的区别使用)
1 | const scaleNames = { |