2

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 中实现同样的目标?

4

1 回答 1

2

首先看起来有一个你必须修补的问题。这将在下一个版本中修复:只需将此方法添加到您的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 哈希到 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
于 2019-04-05T22:32:46.897 回答