首先要感谢imooc网的DellLee老师,我的React 是跟着这位老师入门的,有兴趣的同学可以了解一下,本博客纯为手记,有什么不对的地方还请不吝赐教!
话不多说先上代码!
import React,{ Component,Fragment } from 'react';
import 'antd/dist/antd.css';
import { Input,Button,List } from 'antd';
import store from './store';
import {getInputChangeAction ,getAddItemAction,getDeleteItemAction} from "./store/actionCreators";
class Todolist extends Component{
constructor(props){
super(props);
this.state = store.getState();
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleInputChange= this.handleInputChange.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.handleBtnDelete = this.handleBtnDelete.bind(this);
store.subscribe(this.handleStoreChange);
}
render(){
return (
<Fragment>
<div style={{marginTop:'10px',marginLeft:'10px'}}>
<Input value={this.state.inputValue}
placeholder='to do'
style={{width: '300px',marginRight:'10px'}}
onChange={this.handleInputChange}
/>
<Button type="primary" onClick={this.handleBtnClick} >提交</Button>
<List
bordered
dataSource={this.state.list}
renderItem={(item,index) => (<List.Item key = {index} onClick = {this.handleBtnDelete}>{item}</List.Item>)}
style={{marginTop:'10px',width: '300px'}}
/>
</div>
</Fragment>
)
}
handleInputChange(e){
const action = getInputChangeAction(e.target.value);
store.dispatch(action);
}
handleStoreChange(){
this.setState(store.getState());
}
handleBtnClick(){
const action = getAddItemAction();
store.dispatch(action);
}
handleBtnDelete(){
const action = getDeleteItemAction(this.props.index);
store.dispatch(action);
}
}
export default Todolist;
上面的代码中使用了
rudex
技术,并且使用了
antd design
的UI框架,还没学到的同学需要也没关系,因为拆分组件的理念和
rudex
的关系不是很大!那么,该说一说上面的的代码了,首先上面的代码给我们最直观的感受是什么?维护性差!是的在一个组件中既有UI又有逻辑,这是很不利于测试和维护的,因为我们很不容易弄明白如果这个组件出现问题的了,是UI部分出现问题还是逻辑部分出现问题!所以,聪明的办法就是把逻辑和UI进行分离,UI组件专门用来渲染页面,逻辑组件专门用来逻辑处理!
那么问题来了,我们怎么去进行拆分呢?相信大家对组件怎么传递方法和状态的方法已经很熟悉了,下面我们把刚刚的
TodoList
产分为
Todolist
和
TodulistUI
两个组件,那我就话不多说,直接上代码!
TodoList.js
import React,{ Component,Fragment } from 'react';
import 'antd/dist/antd.css';
import store from './store';
import {getInputChangeAction ,getAddItemAction,getDeleteItemAction} from "./store/actionCreators";
import TodoListUI from "./TodoListUI";
class Todolist extends Component{
constructor(props){
super(props);
this.state = store.getState();
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleInputChange= this.handleInputChange.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.handleBtnDelete = this.handleBtnDelete.bind(this);
store.subscribe(this.handleStoreChange);
}
render(){
return (
<TodoListUI
inputValue = {this.state.inputValue}
list = {this.state.list}
handleInputChange = {this.handleInputChange}
handleBtnClick = {this.handleBtnClick}
handleBtnDelete = {this.handleBtnDelete}
/>
)
}
handleInputChange(e){
const action = getInputChangeAction(e.target.value);
store.dispatch(action);
}
handleStoreChange(){
this.setState(store.getState());
}
handleBtnClick(){
const action = getAddItemAction();
store.dispatch(action);
}
handleBtnDelete(){
const action = getDeleteItemAction(this.props.index);
store.dispatch(action);
}
}
export default Todolist;
TodolistUI.js
import React ,{ Component ,Fragment} from 'react';
import { Input,Button,List } from 'antd';
class TodoListUI extends Component{
render(){
return(
<Fragment>
<div style={{marginTop:'10px',marginLeft:'10px'}}>
<Input value={this.props.inputValue}
placeholder='to do'
style={{width: '300px',marginRight:'10px'}}
onChange={this.props.handleInputChange}
/>
<Button type="primary" onClick={this.props.handleBtnClick} >提交</Button>
<List
bordered
dataSource={this.props.list}
renderItem={(item,index) => (<List.Item key = {index} onClick = {this.props.handleBtnDelete}>{item}</List.Item>)}
style={{marginTop:'10px',width: '300px'}}
/>
</div>
</Fragment>
)
}
}
export default TodoListUI;
哈哈,现在是不是逻辑更加清晰了,这次写测试的时候就能很明白的知道哪里出问题了,虽然看着麻烦了一些,但是现在麻烦一点,以后自己维护起来会很方便的!
不过这仍然不是一个最优的优化方案,因为UI组件比较浪费性能,应该把它继续改为无状态组件,但是为了理解起来比较方便在这里就不做更改了!不过想看无状态组件是怎么修改的请点击这里查看
无状态组件
点这里
最后要谢谢大家的阅读,希望大家和我一起成长!