React学习笔记_dotomvc例子
来源:互联网 发布:中国征兵人口数据 编辑:程序博客网 时间:2024/05/17 06:39
todoMvc 例子
一、reducer
combineReducers
const rootReducer = combineReducers({ todos})
初始化:
const initialState = [ { text: 'Use Redux', completed: false, id: 0 }]
添加记录
- 计算ID: maxId + 1
- 设置值
case ADD_TODO: return [ ...state, { id: state.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1, completed: false, text: action.text } ]
根据id 删除
case DELETE_TODO: return state.filter(todo => todo.id !== action.id )
修改text
case EDIT_TODO: return state.map(todo => todo.id === action.id ? { ...todo, text: action.text } : todo )
设置状态
case COMPLETE_TODO: return state.map(todo => todo.id === action.id ? { ...todo, completed: !todo.completed } : todo )
设置全选
case COMPLETE_ALL: const areAllMarked = state.every(todo => todo.completed) return state.map(todo => ({ ...todo, completed: !areAllMarked }))
清除状态是 completed 的记录
case CLEAR_COMPLETED: return state.filter(todo => todo.completed === false)
二、设置常量
ActionTypes.js
export const ADD_TODO = 'ADD_TODO'export const DELETE_TODO = 'DELETE_TODO'export const EDIT_TODO = 'EDIT_TODO'export const COMPLETE_TODO = 'COMPLETE_TODO'export const COMPLETE_ALL = 'COMPLETE_ALL'export const CLEAR_COMPLETED = 'CLEAR_COMPLETED'
TodoFilters.js
export const SHOW_ALL = 'show_all'export const SHOW_COMPLETED = 'show_completed'export const SHOW_ACTIVE = 'show_active'
三、设置Action
import * as types from '../constants/ActionTypes'export const addTodo = text => ({ type: types.ADD_TODO, text })export const deleteTodo = id => ({ type: types.DELETE_TODO, id })export const editTodo = (id, text) => ({ type: types.EDIT_TODO, id, text })export const completeTodo = id => ({ type: types.COMPLETE_TODO, id })export const completeAll = () => ({ type: types.COMPLETE_ALL })export const clearCompleted = () => ({ type: types.CLEAR_COMPLETED })
设置comtainers
mapStateToProps
mapDispatchToProps
const App = ({todos, actions}) => ( <div> <Header addTodo={actions.addTodo} /> <MainSection todos={todos} actions={actions} /> </div>)const mapStateToProps = state => ({ todos: state.todos})const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(TodoActions, dispatch)})export default connect( mapStateToProps, mapDispatchToProps)(App)
四、component
Header.js
- handleSave 保存 dispatch(action)
export default class Header extends Component { handleSave = text => { if (text.length !== 0) { this.props.addTodo(text) } } render() { return ( <header className="header"> <h1>todos</h1> <TodoTextInput newTodo onSave={this.handleSave} placeholder="What needs to be done?" /> </header> ) }}
TodoTextInput
- state 设置初始状态
- handleSubmit 提交 dispatch(action)
- handleChange handleBlur 组件内部事件,处理组件内部input 值改变后更新内部组件的state,重新渲染
export default class TodoTextInput extends Component { state = { text: this.props.text || '' } handleSubmit = e => { const text = e.target.value.trim() if (e.which === 13) { this.props.onSave(text) if (this.props.newTodo) { this.setState({ text: '' }) } } } handleChange = e => { this.setState({ text: e.target.value }) } handleBlur = e => { if (!this.props.newTodo) { this.props.onSave(e.target.value) } } render() { return ( <input className={ classnames({ edit: this.props.editing, 'new-todo': this.props.newTodo })} type="text" placeholder={this.props.placeholder} autoFocus="true" value={this.state.text} onBlur={this.handleBlur} onChange={this.handleChange} onKeyDown={this.handleSubmit} /> ) }}
五、MainSection 列表
- 全选
- 列表 全部、未完成、已完成
- 列表底部:未完成数量。 切换列表查询状态
- state 初始状态:显示全部记录
- handleClearCompleted 清除已经完成的记录,dispatch actions
- handleShow 根据状态改变列表展示,内部事件。
- renderToggleAll全选
- renderFooter 列表底部
const TODO_FILTERS = { [SHOW_ALL]: () => true, [SHOW_ACTIVE]: todo => !todo.completed, [SHOW_COMPLETED]: todo => todo.completed}export default class MainSection extends Component { state = { filter: SHOW_ALL } handleClearCompleted = () => { this.props.actions.clearCompleted() } handleShow = filter => { this.setState({ filter }) } renderToggleAll(completedCount) { const { todos, actions } = this.props if (todos.length > 0) { return ( <span> <input className="toggle-all" type="checkbox" checked={completedCount === todos.length} /> <label onClick={actions.completeAll}/> </span> ) } } renderFooter(completedCount) { const { todos } = this.props const { filter } = this.state const activeCount = todos.length - completedCount if (todos.length) { return ( <Footer completedCount={completedCount} activeCount={activeCount} filter={filter} onClearCompleted={this.handleClearCompleted} onShow={this.handleShow} /> ) } } render() { const { todos, actions } = this.props const { filter } = this.state const filteredTodos = todos.filter(TODO_FILTERS[filter]) const completedCount = todos.reduce((count, todo) => todo.completed ? count + 1 : count, 0 ) return ( <section className="main"> {this.renderToggleAll(completedCount)} <ul className="todo-list"> {filteredTodos.map(todo => <TodoItem key={todo.id} todo={todo} {...actions} /> )} </ul> {this.renderFooter(completedCount)} </section> ) }}
六、TodoItem 列表项
- state 初始状态,不能编辑
- handleDoubleClick 双击后,可编辑
- handleSave 编辑状态下,修改 dispatch action
- render 渲染,根据editing 是否可编辑渲染不同的组件
export default class TodoItem extends Component { state = { editing: false } handleDoubleClick = () => { this.setState({ editing: true }) } handleSave = (id, text) => { if (text.length === 0) { this.props.deleteTodo(id) } else { this.props.editTodo(id, text) } this.setState({ editing: false }) } render() { const { todo, completeTodo, deleteTodo } = this.props let element if (this.state.editing) { element = ( <TodoTextInput text={todo.text} editing={this.state.editing} onSave={(text) => this.handleSave(todo.id, text)} /> ) } else { element = ( <div className="view"> <input className="toggle" type="checkbox" checked={todo.completed} onChange={() => completeTodo(todo.id)} /> <label onDoubleClick={this.handleDoubleClick}> {todo.text} </label> <button className="destroy" onClick={() => deleteTodo(todo.id)} /> </div> ) } return ( <li className={classnames({ completed: todo.completed, editing: this.state.editing })}> {element} </li> ) }}
七、Footer底部
- renderTodoCount 显示未处理条数
- renderFilterLink 状态 button 可切换状态: ALL、Active、Completed
- renderClearButton 清除 Completed 状态的数据,dispatch action
const FILTER_TITLES = { [SHOW_ALL]: 'All', [SHOW_ACTIVE]: 'Active', [SHOW_COMPLETED]: 'Completed'}export default class Footer extends Component { renderTodoCount() { const { activeCount } = this.props const itemWord = activeCount === 1 ? 'item' : 'items' return ( <span className="todo-count"> <strong>{activeCount || 'No'}</strong> {itemWord} left </span> ) } renderFilterLink(filter) { const title = FILTER_TITLES[filter] const { filter: selectedFilter, onShow } = this.props return ( <a className={classnames({ selected: filter === selectedFilter })} style={{ cursor: 'pointer' }} onClick={() => onShow(filter)}> {title} </a> ) } renderClearButton() { const { completedCount, onClearCompleted } = this.props if (completedCount > 0) { return ( <button className="clear-completed" onClick={onClearCompleted} > Clear completed </button> ) } } render() { return ( <footer className="footer"> {this.renderTodoCount()} <ul className="filters"> {[ SHOW_ALL, SHOW_ACTIVE, SHOW_COMPLETED ].map(filter => <li key={filter}> {this.renderFilterLink(filter)} </li> )} </ul> {this.renderClearButton()} </footer> ) }}
阅读全文
0 0
- React学习笔记_dotomvc例子
- REACT NATIVE + REDUX 初学者学习笔记 例子 @吉他码农
- React学习学习笔记
- REACT学习笔记
- React.js学习笔记
- react学习笔记
- react 学习笔记1
- React学习笔记
- React-Native 学习笔记
- React学习笔记
- React学习笔记
- REACT学习笔记
- react native学习笔记
- react学习笔记
- react-redux 学习笔记
- React学习笔记
- React学习笔记(1)
- React学习笔记(2)
- gitlab nginx 服务当掉问题解决
- Postman使用官方文档翻译--17拦截器捕捉请求扩展使用
- 【jmeter-maven-plugin】五、修改属性
- (接上一篇)二叉树的基本应用举例
- 统计学习方法 第1章 统计学习方法概论
- React学习笔记_dotomvc例子
- hive UDF自定义函数 map处理
- DECLARE_HANDLE宏解析
- MySQL中多表删除方法
- Postman使用官方文档翻译--18脚本语言转换
- FPGA学习笔记1——VGA显示
- Netty学习-非常好的博客
- layer弹窗的一些样式问题
- 64位Linux下安装mysql-5.7.13-linux-glibc2.5-x86_64