【问题标题】:React Childs component changes his parents stateReact Childs 组件改变了他的父母状态
【发布时间】:2020-10-10 00:06:57
【问题描述】:

我正在处理我的第一个更大的 react 项目,发现了这个我不知道如何解决的错误/功能。

问题

我想通过模态编辑用户。我打开了它,但是当我在现场更改某些内容时,父组件的状态也会发生变化。子组件在没有传递函数的情况下改变父状态。

我的方法

我尝试更改变量名称,因为我认为更改父组件状态是不可能的。然后我在状态改变时开始记录。在句柄更改中第一次调用this.props.log() 时,状态已更改。

父组件

class UserAdminPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            performingAction: false,
            editorIsOpened: false,
            selectedUser: {}
        }
    }

    componentDidMount() {
        userService.getAll().then(res => {
            const users = res;
            this.setState({users});
        })
    }

    openEditModal = id => {
        const user = this.state.users.filter(u => u.id === id)[0];
        this.setState({selectedUser: user}, () => {
            this.setState({editorIsOpened: true})
            console.log("Selected user", this.state.selectedUser);
        });
    }
    closeModal = () => {
        console.log("Close values",this.state.users, this.state.selectedUser);

        /*if (!save) {
            console.log("Throwing away");
            this.setState({editorIsOpened: false});
            return;
        }
        console.log("Saving");
        this.setState({editorIsOpened: false});*/
    }
    log = ()=>{
        console.log("Logged user",this.state.users);
    }

    render() {
        const {users} = this.state;
        return (
            users ? (
                <React.Fragment>
                    <MDBRow className={"my-5"}/>
                    <UserTable users={users} openEditModal={this.openEditModal}
                               performingAction={this.state.performingAction}/>
                    {this.state.editorIsOpened && <UserEditorModal user={this.state.selectedUser}
                                                                   closeModal={this.closeModal} log={this.log}/>}
                </React.Fragment>
            ) : (
                <LaunchScreen/>
            )
        )
    }
}

还有孩子

class UserEditorModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedUser: props.user
        }
        console.log("Modal user",this.state.selectedUser)
    }

    handleChange = (e) => {
        this.props.log();//here is different output
        const [field, value] = [e.target.name, e.target.value]
        const parsedValue = parseInt(value)
        const user = this.state.selectedUser;
        user.hasOwnProperty(field) ? user[field] = isNaN(parsedValue)?value:parsedValue : console.error(`${field} not found on ${user}`);
        this.setState({selectedUser:user});
        this.props.log();
    }

    render() {
        const user = this.state.selectedUser;
        const modal = true;
        return (
            <React.Fragment>
                <MDBModal isOpen={modal} toggle={() => this.props.closeModal(null, false)} fullHeight
                          position="right">
                    <MDBModalHeader toggle={() => this.props.closeModal()}>User editor</MDBModalHeader>
                    <MDBModalBody>
                        <MDBRow>
                            <MDBCol size="3">
                                <MDBInput type='number' name="karma" label="Karma" value={user.karma}
                                          onChange={e => this.handleChange(e)}/>
                            </MDBCol>
                            <MDBCol size="3">
                                <MDBInput type='number' name="money" label="Money" value={user.money}
                                          onChange={e => this.handleChange(e)}/>
                            </MDBCol>
                            <MDBCol>
                                <MDBInput type="text" value={user.email} disabled/>
                            </MDBCol>
                        </MDBRow>
                        <MDBRow>
                            <MDBCol size="md">
                                <MDBInput type='text' name="firstName" label="First name" value={user.firstName}
                                          onChange={e => this.handleChange(e)}/>
                            </MDBCol>
                            <MDBCol size="md">
                                <MDBInput type='text' name="lastName" label="Last name" value={user.lastName}
                                          onChange={e => this.handleChange(e)}/>
                            </MDBCol>
                        </MDBRow>
                    </MDBModalBody>
                    <MDBModalFooter>
                        <MDBBtn color="secondary"
                                onClick={() => this.props.closeModal()}>Close</MDBBtn>
                        <MDBBtn color="primary" onClick={() => this.props.closeModal()}>Save
                            changes</MDBBtn>
                    </MDBModalFooter>
                </MDBModal>
            </React.Fragment>
        );
    }
}```
I must missing something but couldnt find it. Hope you can find it and help me once again

【问题讨论】:

  • “我认为更改父组件状态是不可能的。” 我有一个类似问题的答案,可能对您有所帮助,How to set one component's state from another component in React,希望对您有所帮助!
  • 什么状态正在改变?
  • 哦,我知道如何更改父组件状态,但是 UserModal 组件更改 UserAdminPage 组件状态而没有通过功能。

标签: javascript reactjs ecmascript-6 single-page-application mdbootstrap


【解决方案1】:

猜猜这是因为您正在使用引用来更改状态。 所以最终当你改变子组件的状态时,父组件的状态也会改变,但父组件不会重新渲染。

constructor(props) {
        super(props);
        this.state = {
            selectedUser: {...props.user}
        }
        console.log("Modal user",this.state.selectedUser)
    }

尝试在您的孩子身上使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2021-03-08
    • 2022-07-06
    • 2020-06-18
    相关资源
    最近更新 更多