Skip to content

UI组件和容器组件

UI组件

  • 负责页面的渲染

容器组件

  • 负责页面的逻辑

无状态组件

  • 当一个组件只有一个render的时候,就可以定义为无状态组件,定义为无状态组件将提升性能和加载速度。(无生命周期函数、也不会真正的实现组件的实例)

代码拆分结果示例

import React, { Component } from "react";
import store from "./store";
import TodoListUI from './TodoListUI';

class TodoList extends Component {

    constructor(props) {
        super(props);
        this.state = store.getState()
        this.handleInputChange = this.handleInputChange.bind(this)
        this.handleStoreChange = this.handleStoreChange.bind(this)
        this.handleBtnClick = this.handleBtnClick.bind(this)
        this.handleItemDelete = this.handleItemDelete.bind(this)
        // 自动订阅store,监听store的内容
        store.subscribe(this.handleStoreChange);
    }

    render() {
        // 拆分UI组件
        return <TodoListUI
            inputValue={this.state.inputValue}
            handleInputChange={this.handleInputChange}
            handleBtnClick={this.handleBtnClick}
            list={this.state.list}
            handleItemDelete={this.handleItemDelete}
        />
    }

    handleInputChange(e) {
        const value = e.target.value;
        const action = {
            type: 'change_input_value',
            value: value
        }
        store.dispatch(action)
    }

    handleStoreChange () {
        this.setState(store.getState())
    }

    handleBtnClick() {
        const value = this.state.inputValue
        const action = {
            type: 'change_child_value',
            value: value
        }
        store.dispatch(action);
    }

    handleItemDelete(index) {
        const action = {
            type: 'del_child_value',
            index: index
        }
        console.log(action)
        store.dispatch(action)
    }
}

export default TodoList
import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem";
import './style.css'

class TodoListUI extends Component {
    render () {
        return (
            <Fragment>
                <div>
                    <label htmlFor="insertArea">输入内容</label>
                    <input
                        id="insertArea"
                        className="input"
                        value={this.props.inputValue}
                        onChange={this.props.handleInputChange}
                    />
                    <button onClick={this.props.handleBtnClick}>提交</button>
                </div>
                <ul>
                    {
                        // 渲染数据
                        this.props.list.map((item, index) => {
                            return (
                                <TodoItem
                                    itemVal={item}
                                    index={index}
                                    del={this.props.handleItemDelete}
                                />
                            )
                        })
                    }
                </ul>
            </Fragment>
        )
    }
}

export default TodoListUI;
import React, { Fragment } from "react";
import TodoItem from "./TodoItem";
import './style.css'

const TodoListUI = (props) => {
    return (
        <Fragment>
            <div>
                <label htmlFor="insertArea">输入内容</label>
                <input
                    id="insertArea"
                    className="input"
                    value={props.inputValue}
                    // 改变handleInputChange的this指向
                    onChange={props.handleInputChange}
                    // 构建一个引用,这个引用叫input,指向input指定当前input的dom节点
                />
                <button onClick={props.handleBtnClick}>提交</button>
            </div>
            <ul>
                {
                    // 渲染数据
                    props.list.map((item, index) => {
                        return (
                            <TodoItem
                                // 父组件向子组件传值、方法,子组件可以通过props调用
                                itemVal={item}
                                index={index}
                                del={props.handleItemDelete}
                            />
                        )
                    })
                }
            </ul>
        </Fragment>
    )
}

export default TodoListUI;

补充

// 子组件原始写法,将子组件值index传输给父组件
··· ···
<button onClick={this.handleItemDelete.bind(this, index)}></button>
··· ···



// 将子组件拆分成UI组件后,UI组件向容器组件传输值,将index传输给父组件
··· ···
<button onClick={(index) => {this.props.handleItemDelete(index)}}></button>
··· ···