赵走x博客
网站访问量:151849
首页
书籍
软件
工具
古诗词
搜索
登录
49、Flux:理念、回顾Whinepad
48、lint、Flow、测试与复验:测试
47、lint、Flow、测试与复验:Flow
46、lint、Flow、测试与复验:ESLint
45、lint、Flow、测试与复验:package.json
44、构建实例应用:<Whinepad>
43、构建实例应用:应用配置
43、构建实例应用:<Excel>:改进的新版本
42、构建实例应用:组件:对话框
41、构建实例应用:组件:Actions
39、构建实例应用:表单:Form
38、构建实例应用:表单:<FormInput>“工厂组件”
37、构建实例应用:表单:Rating组件
36、构建实例应用:表单:Suggest
35、构建实例应用:Button组件
34、构建实例应用:组件
33、构建实例应用:Whinepad v.0.0.1
32、发布
31、开始构建
30、安装必备工具
29、为应用开发做准备:一个模板应用
28、JSX 和表单
27、JSX 和HTML 的区别
26、在JSX 中返回多个节点
25、展开属性
24、HTML 实体
23、JSX入门
22、Excel:一个出色的表格组件:下载表格数据
21、Excel:一个出色的表格组件:即时回放
20、Excel:一个出色的表格组件:搜索
19、Excel:一个出色的表格组件:编辑数据
18、Excel:一个出色的表格组件:排序
17、Excel:一个出色的表格组件
16、 PureRenderMixin
15、 性能优化:避免组件更新
14、 生命周期示例:使用子组件
13、组件生命周期示例:使用mixin
12、组件:生命周期方法
11、中途改变属性
10、从外部访问组件
9、在初始化state 时使用props:一种反模式
8、 props 与state
7、关于DOM 事件的说明
6、组件:带状态的文本框组件
5、组件的state
4、组件的propTypes
3、组件的属性
2、组件的基础
1、Hello World
50、Flux:Store
37、构建实例应用:表单:Rating组件
资源编号:76090
书籍
React快速上手开发
热度:81
这个应用是用于对已品尝酒类记录笔记的。最偷懒的一种记录方法就是进行星级评分,比如从一星到五星。
这个应用是用于对已品尝酒类记录笔记的。最偷懒的一种记录方法就是进行星级评分,比如从一星到五星。 通过一些可配置的选项,可以让这个星级评分组件变为高度可重用。 * 显示的星级数量可以为任意数值。默认值是5,但是也可以变为其他数值,比如11。 * 只读属性。有些时候你不愿让重要的评分数据因为用户误点击而丢失。 首先在发现工具中编写测试(如图6-5 所示): ```
Rating
No initial value:
Initial value 4:
This one goes to 11:
Read-only:
```  图6-5:星级评分组件 在编写具体逻辑之前,需要设置属性类型,并列出需要维护的状态: ``` import classNames from 'classnames' import React,{Component} from 'react' // 从 React v15.5 开始 ,React.PropTypes 助手函数已被弃用,我们建议使用 prop-types 库 来定义contextTypes。 import PropTypes from 'prop-types' class Rating extends Component{ constructor(props){ super(props); this.state={ rating:props.defaultValue, tmpRating:props.defaultValue } } /* 更多方法 */ } Rating.propTypes={ defaultValue:PropTypes.number, readonly:PropTypes.bool, max:PropTypes.number }; Rating.defaultProps={ defaultValue:0, max:5 }; export default Rating ``` 这些属性的作用一目了然:max 代表星星的数量,readonly 决定组件是否只读。在state中,rating 属性对应当前的评分,tmpRating 则对应用户把鼠标放在星星上移动但尚未点击提交时显示的评分。 接下来编写一些辅助函数,帮助我们处理用户与组件进行交互时发生的状态变化: ``` getValue(){ //我们的所有输入组件提供了这个函数 return this.state.rating; } setTemp(rating){ //用户把鼠标方在组件上时,调用该方法 this.setState({tmpRating:rating}) } setRating(rating){ //用户点进组件时,调用该方法 this.setState({ tmpRating:rating, rating:rating }); } reset(){ //用户把鼠标移开时,调用该方法 this.setTemp(this.state.rating); } componentWillReceiveProps(nextProps, nextContext) { //响应组件外部的变化 this.setRating(nextProps.defaultValue); } ``` 最后实现render() 方法,其逻辑包括以下两点。 * 渲染星星的循环,循环次数从1 开始,到this.props.max 结束。星星可以用符号☆ 表示。当星星包含类名RatingOn 时,颜色变为黄色。 * 一个隐藏的`
`表单域,可以像真正的表单输入框那样使评分的值通过常用的方法取值(和任何普通的`
` 标签一样): ``` render() { const stars=[]; for(let i=1;i
☆ ); } return (
{stars} {this.props.readonly || !this.props.id?null:
}
) } ``` 在这里有一个地方需要注意,那就是bind 方法的使用。在渲染星星的循环中,绑定当前循环中i 的值很合理,但为什么要使用this.reset.bind(this) 呢?事实上,这是在使用ESclass 语法时完成绑定的一种方式。一共有三种方法可以完成绑定: * 使用this.method.bind(this),正如你在上述例子中所看到的那样; * 使用箭头函数会自动进行绑定,比如(_unused_event_) => this.method(); * 在构造函数中一次性绑定。 关于第三种方法,具体做法如下: ``` class Comp extents Component { constructor(props) { this.method = this.method.bind(this); } render() { return
} } ``` 这种做法的一个优点是,你可以像以前(使用React.createClass({}) 时)一样,直接使用this.method 的引用。另一个优点是只需绑定一次即可,不需要在每次调用render() 方法时都绑定。它的不足之处在于会在控制器中增添更多的模板代码。