了解Redux的HOC

时间:2018-09-08 12:51:02

标签: javascript reactjs redux higher-order-functions

我有一个用户组件,只显示用户列表。我尝试将其包装在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...一词刚刚出现在屏幕上。并且propName正以undefined

通过

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

1 个答案:

答案 0 :(得分:2)

评论后更新

我的以下回答是一个误导性的回答,因为当时我还没有正确理解您的意图。另外,我对不获取props的解释是错误的。的确,如果我们不渲染组件,但是您在这里做。所以,问题不在于此。

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

  • 您正在导出的是HOC函数,而不是此处的包装函数。它来自您的Users文件,但不导出实际的Users组件。这很重要。
  • 您的父级第一次渲染,并且渲染导出的HOC组件。
  • 您的子组件呈现为Loading,而不是Users
  • Loading中,您的users属性为空,因此您会看到正在加载...
  • 您的Users组件再也不会渲染。因此,获取那里的用户不会更新状态。

您的解决方案是从Users中提取提取内容并提供给该组件。大概在父母一方。所以:

  • 父级获取用户,然后渲染自身及其所有子级。
  • 您的Loading HOC组件将第二次渲染。

我不知道您打算如何使用此HOC,但如果我理解正确(因为我对HOC经验不足),问题是您没有将任何prop传递给Loading功能。这是因为您没有在此处将其用作常规组件。这是一个函数,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));

应该工作吗?

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