Javascript &引用;这";高阶组分中的反应
我想将共享功能从react组件移动到更高阶的组件,如下所示:Javascript &引用;这";高阶组分中的反应,javascript,reactjs,Javascript,Reactjs,我想将共享功能从react组件移动到更高阶的组件,如下所示: function withListFunctions(WrappedComponent) { return class extends React.Component { constructor(props) { super(props); } // my shared functionality deleteItem() {
function withListFunctions(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props);
}
// my shared functionality
deleteItem() {
// Do something, then ...
this.setState({itemDeleted: true});
}
render() {
return (
<WrappedComponent
deleteItem={this.deleteItem}
/>
);
}
}
。。但是我想绑定包装好的组件。所以我在包装组件的构造函数中尝试的是
this.props.deleteItem = this.props.deleteItem.bind(this);
但这只是导致了一个“无法分配到只读属性”错误,因为react道具是只读的
我知道我可以将状态项存储在HOC中,并将其作为道具传递下去。但它将不再被其他包装组件函数访问(可写),对吗?我想知道是否有一种方法可以共享未绑定的函数,然后将其绑定到已包装的实例 [编辑]我将Abdul Rauf的答案标记为“已接受”,不过我想声明Karen Grigoryan的答案是我实际使用的解决方案,因为它很有效,而且似乎正好适合我的应用程序的复杂性 我知道我可以将状态项存储在HOC中并传递它
作为道具放下。但它将不再可访问(可写) 通过其他包装组件函数,对吗 您应该将共享状态存储在HOC中。您可以将多个状态更新方法传递给包装好的组件,这些组件可以在内部调用以间接更新状态 如果您不想传递多个状态更新方法,则我们有2个选项: 选项1:在HOC中创建一个
分派方法,该方法执行操作
和可选的有效负载
,并将其传递给包装组件
// Do not mutate state in reducer. always return a new state
reducer(state, action) {
switch (action.type) {
case 'delete':
// return final state after delete
case 'add':
// return final state after add using action.payload
case 'update':
// return final state after update using action.payload
default:
// A reducer must always return a valid state.
// Alternatively you can throw an error if an invalid action is dispatched.
return state;
}
}
dispatch(action) {
const updatedState = this.reducer(this.state, action)
this.setState(updatedState);
}
选项2:如果可以使用最新的react with hooks支持,请使用
我想知道是否有一种方法可以共享未绑定函数,然后
将其绑定到包装的实例
从技术上讲,您可以这样做()。但由于许多原因,这被认为是一种不好的做法。其中很少有:
它违反了封装原则。(状态在子组件中,状态更新逻辑在父组件中)。父组件不应该知道关于子组件状态的任何信息
道具可以随时间变化,但这不会自动反映在派生的实例属性/字段中
道具是只读的
React元素是不可变的。创建元素后,不能更改其子元素或属性。元素就像电影中的单个帧:它表示某个时间点的UI
因此,从技术上讲,将deleteItem
绑定到WrappedComponent
上下文的方法之一就是在WrappedComponent
构造函数中绑定它:
this.deleteItem=this.props.deleteItem.bind(this)代码>注意:确定这是否有效,但您尝试过吗this.deleteItem=this.deleteItem.bind(WrappedComponent)
@PatrickHund您的解决方案绑定到类而不是实例您是对的,这不起作用虽然React更喜欢组合而不是继承,但如果有意义,您仍然可以使用继承。如果您想创建一个没有继承的包装组件,我会将要包装的组件作为一个道具传递。“但是它将不再被其他包装组件函数访问(可写),对吗?”不,如果您像setDeletedItem={this.setDeletedItem}这样传递道具,它将是可写的
转化为你能用几句话具体说明为什么Karen Grigoryan的回答被认为是一种不好的做法吗?它是否有具体的缺点,或者只是没有按照框架的观点来组织事情?
// Do not mutate state in reducer. always return a new state
reducer(state, action) {
switch (action.type) {
case 'delete':
// return final state after delete
case 'add':
// return final state after add using action.payload
case 'update':
// return final state after update using action.payload
default:
// A reducer must always return a valid state.
// Alternatively you can throw an error if an invalid action is dispatched.
return state;
}
}
dispatch(action) {
const updatedState = this.reducer(this.state, action)
this.setState(updatedState);
}