【问题标题】:Material-UI component not being rendered with react-rails prerenderMaterial-UI 组件未使用 react-rails prerender 渲染
【发布时间】:2018-04-30 06:54:52
【问题描述】:

我正在尝试使用 javascript 动态包含一个反应组件,即用户可以单击“添加位置”并将一个表单添加到页面中。此表单包含一个使用 material-ui 的自动完成组件的反应组件。

以下是单击按钮时动态添加的表单代码:

<div class="grid-x grid-margin-x grid-margin-y grid-padding-x grid-padding-y align-center">          
  <div class="cell medium-6">
        <div class="field">
          <%= f.label :activity_place %><br/>
          <%= react_component("PlaceSearch", {}, {prerender: true}) %>
        </div>
    </div>
    <div class="cell medium-6">
        <div class="field">
          <%= f.label :activity_time %><br/>
          <%= f.select(:activity_time, Constants::ACTIVITY_TIMES) %>
        </div>
    </div>
</div>

以下是组件的代码(不包括导入):

class PlaceSearch extends React.Component {
    state = {
    checked: false,
    dataSource: [
      {
        text: 'text-value1',
        value: (
          <MenuItem
            primaryText="text-value1"
            secondaryText="&#9786;"
          />
        ),
      },
      {
        text: 'text-value2',
        value: (
          <MenuItem
            primaryText="text-value2"
            secondaryText="&#9786;"
          />
        ),
      },
    ]
  }


  render () {
    return (
      <MuiThemeProvider muiTheme={getMuiTheme({userAgent: (typeof navigator !== 'undefined' && navigator.userAgent) || 'all' })}>
        <div>
          <AutoComplete
            hintText="text-value data"
            filter={AutoComplete.noFilter}
            dataSource={this.state.dataSource}
          />
        </div>
      </MuiThemeProvider>
    );
  }
}

export default PlaceSearch

这个例子是我从 material-ui 的文档中挑选出来的。

除了反应组件外,一切都按预期工作。如果我尝试在动态添加的表单之外的其他地方添加反应组件包含代码,它会按预期工作。

我搜索了有关 material-ui 和 rails 的不同论坛,但找不到此特定问题的解决方案。

【问题讨论】:

    标签: ruby-on-rails reactjs material-ui


    【解决方案1】:

    您应该将状态声明放在构造函数中:

    class PlaceSearch extends React.Component {
        constructor() {
            super();
            this.state = {
            checked: false,
            dataSource: [
               {
                   text: 'text-value1',
                   value: (
                       <MenuItem
                        primaryText="text-value1"
                        secondaryText="&#9786;"
                       />
                   ),
               },
               {
                   text: 'text-value2',
                   value: (
                       <MenuItem
                        primaryText="text-value2"
                        secondaryText="&#9786;"
                       />
                   ),
                }]   
             }
         }
    
    
      render () {
        return (
          <MuiThemeProvider muiTheme={getMuiTheme({userAgent: (typeof navigator !== 'undefined' && navigator.userAgent) || 'all' })}>
            <div>
              <AutoComplete
                hintText="text-value data"
                filter={AutoComplete.noFilter}
                dataSource={this.state.dataSource}
              />
            </div>
          </MuiThemeProvider>
        );   } }
    
    export default PlaceSearch
    

    如果这对您有用,这就是原因:SO Post

    【讨论】:

    • 感谢您的建议,但您的代码出现以下错误:使用 {} 预呈现 PlaceSearch 时遇到错误 #<:programerror: referenceerror: state is not defined>"
    • 对不起,你应该使用 this.state... 我的错。查看我的更新答案
    • 这似乎已经解决了您之前的代码导致的错误,但没有使组件按应有的方式工作,即首先提出问题的原因。
    【解决方案2】:

    最后通过添加手动组件安装代码使其工作,即 ReactRailsUJS.mountComponents() 如 react-rails gem 的 github doc 中所述。没有对组件 JS 文件进行任何更改,而只是对包含它的表单进行了更改。工作代码如下:

    <div class="grid-x grid-margin-x grid-margin-y grid-padding-x grid-padding-y align-center">          
      <div class="cell medium-6">
            <div class="field">
              <%= f.label :activity_place %><br/>
              <%= react_component("PlaceSearch", {}, {prerender: true}) %>
            </div>
        </div>
        <div class="cell medium-6">
            <div class="field">
              <%= f.label :activity_time %><br/>
              <%= f.select(:activity_time, Constants::ACTIVITY_TIMES, include_blank: true) %>
            </div>
        </div>
    </div>
    <script>
        ReactRailsUJS.mountComponents()
    </script>
    

    【讨论】:

    • 我后来在使用 Material-ui 和 react 时遇到了这种方法的问题。我不得不从我的组件渲染视图助手中删除 {prerender: true} 并完全依赖 mountComponents() 方法。否则它会给出客户端 - 服务器类名不匹配错误。
    猜你喜欢
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 2019-12-04
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    相关资源
    最近更新 更多