【问题标题】:Understanding HOCs with Redux用 Redux 理解 HOC
【发布时间】:2018-09-08 12:51:02
【问题描述】:

我有一个只显示用户列表的用户组件。我试图将它包装在 HOC 加载组件中,以便它仅在加载用户后显示,否则显示加载微调器(现在只是文本)

这是我的 HOC:

const Loading = (propName) => (WrappedComponent) => {
  return class extends React.Component{
    render(){
      return this.props[propName].length === 0 ? <div> Loading... </div> : <WrappedComponent {...this.props} />
    }
  }
}

export default Loading;

在我的用户组件的底部我有这个:

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Loading('users')(Users));

目前,Loading... 这个词只停留在屏幕上。并且propNameundefined 的身份通过

我认为由于某种原因,用户组件永远不会被填充。我做错了什么?

【问题讨论】:

  • 你想用 this.props[propName] 做什么?
  • 有道具通过吗?
  • @Think-Twice 我想根据 props 渲染组件
  • 我现在想问你如何获得用户以及如何渲染这个组件。因为我没有从你的问题中得到结构:) 很高兴你解决了你的问题。您可以提供有关解决方案的详细答案并接受它。
  • 干杯,非常感谢!

标签: javascript reactjs redux higher-order-functions


【解决方案1】:

cmets 后更新

我在下面的回答具有误导性,因为当时我没有正确理解您的意图。另外,我关于没有得到props 的解释在某种程度上是错误的。如果我们不渲染组件,这是真的,但你正在这样做。所以,问题不在于这个。

这里的问题是您的Loading 组件在获取用户后没有再次呈现。实际上,您永远不会获取用户 :) 以下是您的应用程序的步骤(可能)。

  • 您正在导出一个 HOC 函数,而不是这里的 Wrapped 函数。它来自您的Users 文件,但它不会导出真正的Users 组件。这很重要。
  • 您的父级第一次渲染,它渲染导出的 HOC 组件。
  • 您的子组件呈现并落入Loading 一个而不是Users 一个。
  • Loading 中,您的users 属性为空,因此您会看到Loading...
  • 您的Users 组件永远不会再次呈现。因此,获取那里的用户不会更新状态。

您的解决方案是从Users 中提取提取并提供此组件。可能在父母那里。所以:

  • Parent 获取用户,然后呈现自己及其所有子项。
  • 您的Loading HOC 组件再次呈现。

我不知道你打算如何使用这个 HOC,但如果我理解正确(因为我对 HOC 没有那么丰富的经验)在你的情况下,问题是你没有将任何 prop 传递给 @987654333 @ 功能。这是因为您在这里没有将它用作常规组件。它是一个函数,propName 这里只是一个参数。

当我们像这样渲染一个无状态函数时:

<Loading propName="foo" />

那么我们的函数就会有一个props 参数。如果我们不这样渲染,就不会有props 参数和props.propName。如果这是错误的,请有人解决这个问题并解释正确的逻辑。所以,你可能想做这样的事情:

class App extends React.Component {
  render() {
    return (
      <div><FooWithLoading /></div>
    );
  }
}

const Loading = (users) => (WrappedComponent) => {
  return class extends React.Component {
    render() {
      return (
        users.length === 0 ? <div> Loading... </div> :
        <WrappedComponent
          users={users}
        />
      );
    }
  }
};

const Foo = props => {
return (
  <div>
    Users: {props.users}
  </div>
);
}

const FooWithLoading = Loading("foobar")(Foo);

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

所以在你的情况下:

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Loading('users')(Users));

应该工作吗?

或者您需要在应用的合适位置正确渲染组件。

【讨论】:

  • 我认为问题不在于 HOC 的定义方式。你刚刚取消了他的咖喱版本。不过,两个 HOC 应该是等价的。
  • @FK82,是的,你是对的。主要问题不是在这里柯里化。我已将其还原为原始版本。
  • @devserkan 我想使用柯里化和 HOC。提高我对它们的了解。我知道如何使用 Loading 组件以传统的反应方式呈现组件
猜你喜欢
  • 1970-01-01
  • 2019-04-06
  • 2020-01-08
  • 2018-04-16
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 2020-11-01
相关资源
最近更新 更多