我正在尝试优雅地重构组件,以便我们可以轻松地将组件用于相同的用例。
我有两个组件,
SelectWarehouse组件将呈现NewPurchaseOrder组件中可用仓库的下拉列表。
父组件有一个状态warehouseId
来跟踪选定的仓库,从我正在执行此操作的子组件更新父组件状态(warehouseId),
父组件
<SelectWarehouse
updateTarget={ ( ghostValue ) => {
this.setState( {
warehouseId: ghostValue // updating the state from child comp. value
}, () => {
console.log( 'yokygoky', this.state.warehouseId )
} )
} }
/>
子组件
handleChangeWarehouse( e ) {
this.setState( {
selectedWarehouse: e.target.value
}, () => {
this.props.updateTarget( e.target.value ) // Updating the parent props
} )
}
现在我要做的是,只从父级发送状态名称而不是发送函数,然后从子组件更新父组件的状态。 它看起来像这样,
<SelectWarehouse
updateTarget={ warehouseId }
/>
然后从子组件更新warehouseId。
有可能吗?
我通过仅发送没有运气的状态来测试它,也不可能只用一个简单的状态来绑定这个上下文。
答案 0 :(得分:1)
您的问题的简单答案将是否。但为什么呢?
您所询问的内容与Angular和Vue.js等框架中支持的双向绑定概念非常相似。这意味着数据将通过一个绑定从子组件流入和流出父组件。 React并不支持这一点,并且非常不鼓励使用这种方法。它总是喜欢单向数据流。
因此,使用React,您可以使用props轻松地从组件树的顶部到底部发送数据。但是如果你想要反向重定向,从下到上,你唯一的选择就是回调。您可以将回调作为prop传递给子组件,它将在数据准备好时使用相关数据调用回调。有时,当我们需要深层嵌套组件之间的通信时,这很难。因此,您需要使用像Redux或React context这样的状态管理库,如果您不是经验丰富的开发人员,则不鼓励使用该库。
为了更好地理解它,我建议您阅读React官方文档中的Thinking in React部分。他们相信这种方法可以让人们更容易理解程序的工作方式而不是神奇的双向绑定。
React使这个数据流明确,使其易于理解 你的程序有效,但确实需要更多的输入 传统的双向数据绑定。
此外,
虽然这听起来很复杂,但实际上只是几行代码。和 它非常清楚您的数据在整个应用中的流动情况。
在您的情况下,可能您必须使用它,重构为其他答案建议的其他格式或使用第三方库,如react-binding(我还没有使用它,所以可以&# 39;推荐)。
答案 1 :(得分:0)
状态是特定于组件范围的东西,因此您不能通过直接访问它来访问和修改另一个组件的状态,您必须调用要更改其状态的特定组件的方法。
因此,您使用的第一种方法是正确的方法。
也许为了使它更清洁,你可以在单独的函数中使用逻辑并将该函数作为prop
传递父
updateTarget = (newValue) => {
this.setState( {
warehouseId: newValue // updating the state from child comp. value
}, () => {
console.log( 'yokygoky', this.state.warehouseId )
} )
}
<SelectWarehouse
updateTarget={ ( ghostValue ) => this.updateTarget(ghostValue) }
/>
答案 2 :(得分:0)
直接从子级更新父组件的状态是不对的。将updateTarget作为func的<SelectWarehouse />
的第一个版本是正确的。
此外,没有必要将warehouseId存储在子组件中的状态中。 warehouseId可以作为道具传递给子组件。
<SelectWarehouse
updateTarget={( ghostValue ) => {
this.setState( {
warehouseId: ghostValue
})
}}
warehouseId={this.state.warehouseId}
/>
答案 3 :(得分:0)
我认为无法从组件本身设置重置道具,有关详情,请参阅link。
您应该调用父方法,然后设置State并将其传递给child。
家长
let data = [{"path":"http://localhost:8091/public/testimg.jpg","type":"image"},{"path":"http://localhost:8091/public/testvideo.mp4","type":"video"}]
Observable.timer(0, 3000)
.map(e => {
console.log(e); return data[e % data.length];
})
.subscribe(item => {
this.activeItem = item;
});
子
updateTarget = (value) => {
this.setState( {
warehouseId: value
})
}
<SelectWarehouse
updateTarget= {this.updateTarget }
/>