状态提升
我们做项目的过程中,有时候需要父组件控制子组件的状态,这个时候,我们可以采用提升子组件的状态,把子组件的状态交给父组件管理。如下图,我们编辑用户信息的时候,希望把弹窗的状态交给列表页,实现过程,如下:
视频教程地址
- 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
- 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
状态提升步骤:
- 在父组件中定义state用来存储子组件的状态
- 将子组件的状态交给props
- 子组件需要更新状态就通知父组件
- 父组件更新state,重新渲染子组件的props
- 子组件更新状态