【问题标题】:React: connected HOC with with callback as propsReact:以回调为道具连接 HOC
【发布时间】:2020-07-15 04:45:49
【问题描述】:

我有几个“愚蠢”的组件。我正在尝试制作一个将它们连接到 Redux 存储的高阶组件,并将回调函数作为道具传递。子组件会调用这个回调函数来响应点击事件。

我正在与范围作斗争。回调函数需要 setState 并且还 dispatch 一个 Redux action。

以下是不起作用的:

//Child Component
class Child extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <button onClick={this.props.callbackFunc}>Click</button>;
  }
}

//callback function
clickCallback(e){
  this.setState({foo: "bar"});
  this.props.dispatch(
    someReduxAction({boo: "baz"})
  );
}

const WithCallbackChunk = (Comp, callback) => {
  return class extends React.Component {
    constructor(props){
      super(props);
      this.callback = callback.bind(this);
    }
    render() { return <Comp callbackFunc={callback} {...this.props} />; }
  }
}

   
//connected comp
const ConnectedChunk = function(comp){
  return connect(
    null,
    {someReduxAction}
  )(WithCallbackChunk(comp));
}

const ConnectedCallbackComp = ConnectedChunk(Child);

export { ConnectedCallbackComp }

我无法在回调中同时获得 setStateprops.dispatch 的正确范围。

提前致谢!

更新/解释

有几个人询问了WithCallbackChunk 的用途。我正在尝试将表示逻辑与表单处理分开。

我的应用程序允许用户构建自定义表单。有一种显示表单预览的编辑模式,表单的这些“块”中的每一个都是上面简化示例中的Child 组件。当该表单发布时,那些子组件(构成该表单)需要变得可交互并连接到 Redux 存储。

我试图通过重用“哑”演示组件来编辑实时表单上下文(因为它们是相同的),从而使事情保持干燥。但表单处理仅在实时上下文中需要。 Child 组件在两种上下文中都有所有 Redux 操作似乎很混乱,所以我试图弄清楚如何通过 props 传递该功能。

我的目标是让子组件只定义 UI,然后让两个不同的“包装器”HOC 组件为各自的上下文提供额外的功能。很明显,我没有做到这一点。也许我以错误的方式思考这个问题?我欢迎有关更好的方法的反馈或建议。

总结这一点的另一种方式是,我正在为 React 的单向数据流而苦苦挣扎。 (信息只会“向下”传递给孩子。)我正在尝试将上下文逻辑从 HOC 向下传递。但是 Child 组件是唯一知道何时调用它的组件(因为它定义了 UI)

【问题讨论】:

  • 我不太明白你想用WithCallbackChunk 做什么。 clickCallback 需要成为班级的一部分。您可以将其定义为const ConnectedCallbackComp = connect(null, {someReduxAction})(Child),而不是返回连接。
  • @Yoshi 我刚刚更新了问题以尝试回答您的问题。如果仍然不清楚我要做什么,请告诉我。
  • 您并没有想错,拥有智能和愚蠢的组件是正确的方法。即使您必须使用 Redux HOC 将其连接到 store,连接的父组件也应该只是一个容器,因此您将拥有 FormFormContainer。所以,它与你现在正在做的模式非常相似。状态设置器将存在于容器中,并将回调作为道具传递给表单。 HOC 通常用于跨组件共享逻辑,尤其是在组件不应该关心细节的情况下。组件应该知道它的状态是如何设置的
  • @Yoshi 我认为 我明白你在说什么:我应该将所有状态逻辑移到容器中,然后将回调函数传递给哑包组件。这是正确的吗?容器将被连接,因此它的范围将包括dispatchsetState 等......换句话说,问题是我试图从外部与包装组件的状态进行交互。如果状态转移到容器中,事情就会变得简单......我想我明白了!

标签: javascript reactjs redux higher-order-components


【解决方案1】:

您将错误的回调传递给包装的组件。传递与内部组件的this 绑定的那个,而不是传递给 HOC 的那个。

const withCallback = (WrappedComponent, callback) => {
  class BaseContainer extends Component {
    constructor(props) {
      super(props);
      this.callback = callback.bind(this);
    }
    
    render() {
      return (
        <WrappedComponent
          callbackFunc={this.callback} // <-- pass the bound callback to this component
          {...this.props}
        />
      );
    }
  }

  return BaseContainer;
};

在使用 redux 编写时,不要忘记将回调传递给 withCallback HOC。

const ConnectedChunk = connect(
  null,
  {someReduxAction}
)(withCallback(comp, callback));

【讨论】:

  • 虽然这行得通,但我不明白将状态设置器传递给 HOC 的模式。为什么不直接在类中定义方法。
  • @Yoshi 虽然我不同意你的观点,但这不是问题中要问的。我想这被视为 OP 的某种应用 DRY-ness,但这是一个足够简单的错误来修复,所以为什么不帮助他们使其工作。要说其他任何事情,都需要更多问题并获得有关用例的更多背景信息。
  • @DrewReese 这是否也提供对dispatch 的访问权限?我的回调函数调度 Redux 操作。我相信它会作为道具传递给连接的组件,但我一直无法将其置于传递给子组件的回调范围内。
  • @emersonthis 我不明白为什么不这样做。 withCallback 返回一个组件,然后您将其传递给 connect HOC 以将更多状态和调度映射到道具。只需要在编写时也将回调函数传递给withCallback HOC。
  • @DrewReese 谢谢!我想我可能会让我想做的事情过于复杂。我很好奇您是否对我在问题下方的 cmets 中与 Yoshi 讨论的想法有想法。
猜你喜欢
  • 2018-10-13
  • 2021-04-12
  • 2018-08-22
  • 2020-01-16
  • 2019-03-07
  • 2022-01-10
  • 2018-02-15
  • 2019-03-07
  • 1970-01-01
相关资源
最近更新 更多