状态提升

365 阅读1分钟

状态提升

我们做项目的过程中,有时候需要父组件控制子组件的状态,这个时候,我们可以采用提升子组件的状态,把子组件的状态交给父组件管理。如下图,我们编辑用户信息的时候,希望把弹窗的状态交给列表页,实现过程,如下:

视频教程地址

web/react/vue/ts

image.png

4

  1. UserList.tsx用来展示用户列表
import React, {Component} from "react";
import {Button, Space, Table} from "antd";
import EditUser from "./EditUser";

interface IUser {
    id: number
    name: string
}

interface IState {
    userList: IUser[]
    pageSize: number
    page: number
    perPage: number
    totalCount: number
    visible: boolean
    user?: IUser
}

class UserList extends Component<any, IState> {
    constructor(props: any, context: any) {
        super(props, context);
        this.state = {
            userList: [],
            page: 1,
            perPage: 15,
            totalCount: 0,
            pageSize: 0,
            visible: false
        }
    }

    getUserList = (page: number = 1) => {
        let userList: IUser[] = []
        for (let i = 1; i < 10; i++) {
            userList.push({
                id: i,
                name: 'user' + i
            })
        }
        this.setState({
            userList: userList
        })
    }
    onChange = (page: number) => {
        this.getUserList(page)
    }

    componentDidMount() {
        this.getUserList(1)
    }

    deleteUser = (userId: number) => {
        this.setState((state) => ({
            userList: state.userList.filter(user => user.id !== userId)
        }))
    }
    show = (visible: boolean, user?: IUser) => {
        this.setState((state) => ({
            visible: visible,
            user: user,
            userList: state.userList.map((u, _) => {
                if (u.id === user?.id) {
                    return user
                } else {
                    return u
                }
            })
        }))
    }

    render() {
        return (
            <>
                <EditUser visible={this.state.visible} user={this.state.user} callback={this.show}/>
                <Table
                    pagination={{
                        position: ['bottomCenter'],
                        total: this.state.totalCount,
                        hideOnSinglePage: true,
                        defaultCurrent: this.state.page,
                        defaultPageSize: this.state.perPage,
                        showSizeChanger: false,
                        onChange: this.onChange
                    }}
                    dataSource={this.state.userList}
                    rowKey={'id'}
                >
                    <Table.Column
                        title={'ID'}
                        dataIndex={'id'}/>
                    <Table.Column
                        title={'姓名'}
                        dataIndex={'name'}/>
                    <Table.Column
                        title={'操作'}
                        render={(user: IUser) => (
                            <Space>
                                <Button type='primary' onClick={() => {
                                    this.show(true, user)
                                }}>编辑用户</Button>
                            </Space>
                        )}
                    />
                </Table>
            </>
        )
    }
}

export default UserList

  1. EditUser.tsx用来修改数据
import React, {Component, RefObject} from "react";
import {Button, Form, Input, Modal, Space} from "antd";
import {FormInstance} from "antd/es/form";

const tailLayout = {
    wrapperCol: {offset: 8, span: 16},
};

interface IUser {
    id: number
    name: string
}

interface IProps {
    visible: boolean
    user?: IUser
    callback: (visible: boolean, user?: IUser) => void
}

class EditUser extends Component<IProps, any> {
    formRef: RefObject<FormInstance>

    constructor(props: IProps, context: any) {
        super(props, context);
        this.formRef = React.createRef<FormInstance>();
    }

    handleCancel = () => {
        this.props.callback(false)
    }
    saveUser = (user: IUser) => {
        this.props.callback(false, {...this.props.user, ...user})
    }

    render() {
        this.formRef.current?.setFieldsValue({...this.props.user})
        return (
            <>
                <Modal
                    title="编辑用户信息"
                    visible={this.props.visible}
                    onCancel={this.handleCancel}
                    cancelText='取消'
                    okText='确认'
                    footer={null}
                >
                    <Form
                        ref={this.formRef}
                        onFinish={this.saveUser}
                        initialValues={{
                            ...this.props.user
                        }}
                    >
                        <Form.Item
                            shouldUpdate={(prevValues, curValues) => prevValues.additional !== curValues.additional}
                            label='姓名'
                            name='name'
                            rules={[{required: true, message: '用户姓名不可以为空'}]}
                        >
                            <Input/>
                        </Form.Item>
                        <Form.Item {...tailLayout}>
                            <Space>
                                <Button type="primary" htmlType="submit">
                                    提交
                                </Button>
                            </Space>
                        </Form.Item>
                    </Form>
                </Modal>
            </>
        )
    }
}

export default EditUser

状态提升步骤:

  1. 在父组件中定义state用来存储子组件的状态
  2. 将子组件的状态交给props
  3. 子组件需要更新状态就通知父组件
  4. 父组件更新state,重新渲染子组件的props
  5. 子组件更新状态