【问题标题】:Higher-order components in HyperstackHyperstack 中的高阶组件
【发布时间】:2019-04-06 06:42:34
【问题描述】:

有一个使用 javascript 库的常见用例,您希望用高阶组件来装饰您的组件。

例如,material-ui 库包含一个样式化高阶组件withStyles

在javascript中,你会这样做

import { withStyles } from '@material-ui/core';

const styles = {
  example: {
    padding: 8
  }
}
const SomeComponent = ({classes}) => <div className={classes.example}>I'm a component</div>;

export default withStyles(SomeComponent);

如何在 Hyperstack 中实现同样的效果?

【问题讨论】:

    标签: javascript ruby reactjs hyperstack


    【解决方案1】:

    首先看起来有一个issue 你必须修补。这将在下一个版本中修复:只需将此方法添加到您的 Hypercomponent 基类 (app/hyperstack/components/hypercomponent.rb)

    def self.to_n
      Hyperstack::Internal::Component::ReactWrapper.create_native_react_class(self)
    end
    

    现在如果你有以下样式:

    MY_STYLES = {root: {backgroundColor: 'red'}}
    

    以及您要设置样式的组件:

    class StyleTest < HyperComponent
      param :some_param
      param :classes
      render do
        DIV(class: classes[:root]) { some_param }
      end
    end
    

    你可以这样做:

    class StyledTest1 < HyperComponent
      imports `Mui.withStyles(#{MY_STYLES.to_n})(#{StyleTest.to_n})`
    end
    

    正在发生的事情是我们使用反引号退出 JS 并直接调用 Mui.with_styles 并将其传递给 MY_STYLES(就像在 MUI 文档示例中一样)。 to_n 从 Ruby Hash 转换为 JS 对象。 (当将参数传递给组件时,这是自动的,但对于简单的函数调用则不是这样。)

    然后我们使用 StyleTest 类调用生成的 HOC(也调用 to_n 将 Ruby 类转换为简单的 JS 类。)

    最后,我们将其重新导入到 Hyperstack 组件类中。

    这比我喜欢的要多一些工作,所以我们可以在 HyperComponent 类中添加一个方便的辅助方法:

    class HyperComponent
      include Hyperstack::Component
      include Hyperstack::State::Observable
      param_accessor_style :accessors  # this is now the prefered param style
    
      # patch for issue: https://github.com/hyperstack-org/hyperstack/issues/153
      def self.to_n
        Hyperstack::Internal::Component::ReactWrapper.create_native_react_class(self)
      end
    
      # our helper macro:
      def self.add_styles(style, opts = {})
        imports `Mui.withStyles(#{style.to_n}, #{opts.to_n})(#{superclass.to_n})`
      end
    end
    

    现在我们可以像这样添加样式:

    class StyledTest2 < StyleTest
      add_styles MY_STYLE
    end
    

    现在我们有了一个新的组件类,其中包含我们的样式。

    例如:

    class App < HyperComponent
    
      render do
        DIV do
          StyledTest1(some_param: 'test 1')
          StyledTest2(some_param: 'test 2')
        end
      end
    end
    

    【讨论】:

    • 我的意思不是要澄清一些 cmets。大多数文档使用类似于 @MyParam 的参数样式访问器。这将在未来被弃用,因为它太丑陋了。您可以通过将param_accessor_style :accessors 添加到HyperComponent 基类来获得像我使用的新语法。只是不想让你感到困惑!
    猜你喜欢
    • 2019-05-16
    • 2016-10-17
    • 2018-11-18
    • 2017-10-18
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多