React 拆分组件为UI组件和容器组件

首先要感谢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产分为TodolistTodulistUI两个组件,那我就话不多说,直接上代码!

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组件比较浪费性能,应该把它继续改为无状态组件,但是为了理解起来比较方便在这里就不做更改了!不过想看无状态组件是怎么修改的请点击这里查看无状态组件点这里


最后要谢谢大家的阅读,希望大家和我一起成长!


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值