【问题标题】:Change Parent State from Child Component in React (No Redux)在 React 中从子组件更改父状态(无 Redux)
【发布时间】:2020-08-21 04:19:37
【问题描述】:

上下文:

我正在开发vanilla React 和 React Bootstrap (no redux) 项目来管理我部门的角色。角色列表并不真正相关,但对于上下文想象:管理员、经理、培训师等。

我有一个父组件<RoleContainer key={role} role={role} /> 元素具有以下状态:

this.state = {
  collapsed: true,
  roleAttributes: [],
  roleMembers: [],
  isLoading: true,
};

<RoleContainer /> 内部,有一个<table/> 元素,其中包含一个roleMembers.map,用于循环遍历roleMembers 并动态呈现表格行。因此,对于每个角色成员,您都会获得一个表格行。

问题:

我有一个名为<CreateMemberModal role={role} roleAttributes={roleAttributes} /> 的组件,它是<RoleContainer /> 的子组件,它允许用户POST 一个新的roleMember

目前,我必须将POST 新的roleMember 放入数据库,然后重新加载页面,以便更改可以反映。

当我 POST 一个新用户时,是否有一种可接受的方式(不是反模式或不良做法)在没有 redux 的情况下从子 <CreateMemberModal /> 中更新 <RoleContainer /> 组件的 roleMembers 状态属性?

这将允许我只重新呈现具有新角色成员的 <RoleContainer />,而不是重新加载整个页面。

【问题讨论】:

  • 你发布新角色,然后获取新角色作为响应,并提供从父组件到子组件的回调,然后在新角色保存后传递新角色(作为响应而来) ,然后在父组件中将新角色推送到角色
  • 是否有任何关于如何执行此操作的文档可供您指出?当您说提供回调时,您的意思是我通过 prop 从父级向子级传递一个函数吗?
  • 没错,kiranvj 的回答就是我的意思

标签: javascript reactjs jsx


【解决方案1】:

<RoleContainer />中添加一个方法来更新roleMembers

// bind this in constructor 
updateRoleMembers(newRoleMember) {   
   this.setState((prevState)=> {
       return {roleMembers : prevState.roleMembers.concat([newRoleMember])}
   }
}

现在将此方法传递给CreateMemberModal

<CreateMemberModal role={role} roleAttributes={roleAttributes} updateRoleMembers={this.updateRoleMembers} />

只要你有新的成员角色详细信息,就在&lt;CreateMemberModal 组件中调用this.props.updateRoleMembers(NEW ROLE MEMBER)

是否有任何关于如何执行此操作的文档可供您指出? 当你说提供回调时,你的意思是我通过一个函数 父母给孩子的道具?

查看反应文档here

【讨论】:

  • 感谢您的帮助。这真的很有用。我确实检查了文档,似乎这是一种公认​​的做法。我虽然读过更新父状态的孩子不是一个好习惯。您对此有何看法?
  • @TheDaniel 根据文档将状态提升到父级的推荐方式。如果我们没有 redux 并且想要共享状态,它很有用。
【解决方案2】:

您可以使用回调函数... 我假设您的结构将是这样的......

export class RoleContainer extends React.Component {
    this.state = {
    collapsed: true,
    roleAttributes: [],
    roleMembers: [],
    isLoading: true,
};

yourApiCallToUpdateRoleMembers = () => {
    apiCall().then(response => {
        this.setState({
            roleMembers: response // assuming response has the data
        })

    })
}

render(){
    return <>
        <table>
            {this.state.roleMembers.map(element => <tr></tr>)}
        </table>
        <CreateMemberModal role={role} roleAttributes={roleAttributes} /> // instead of this add a callback function also

        <CreateMemberModal role={role} roleAttributes={roleAttributes} successCb={yourApiCallToUpdateRoleMembers} />
    </>
}
}
 

并且您的子组件正在进行更新数据的后期调用

export function CreateMemberModal(props) {
    makePostCall = () => {
        apiCall().then(response => {
            props.successCb()
        })
    }
}

【讨论】:

  • 感谢您的回复,这很有帮助。我遇到了一些问题,但在检查了 kiranvj 响应并考虑了我的特定组件如何工作后,我能够解决它。你对这个孩子更新父母状态的概念是好是坏有意见吗?
猜你喜欢
  • 2021-04-02
  • 2021-05-21
  • 2021-03-23
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多