【问题标题】:React Error (Only a ReactOwner can have refs.)React 错误(只有 ReactOwner 可以有 refs。)
【发布时间】:2016-06-06 17:09:25
【问题描述】:

我刚刚使用'React-rails' 在我的rails 项目中安装了一个新的react,并在其上添加了searchkit。但我遇到了一些错误。

Uncaught Invariant Violation: addComponentAsRefTo(...): 只有 ReactOwner 可以有 refs。您可能正在向组件添加一个 ref,该组件不是在组件的 render 方法中创建的,或者您加载了多个 React 副本。

app/assets/javascripts/components/search.js.jsx

const host = "http://demo.searchkit.co/api/movies"
const sk = new Searchkit.SearchkitManager(host, {})

var Search = React.createClass({
  render: function() {
    const SearchkitProvider      = Searchkit.SearchkitProvider;
    const Searchbox              = Searchkit.SearchBox;
    const Hits                   = Searchkit.Hits;
    const NoHits                 = Searchkit.NoHits;
    const HitsStats              = Searchkit.HitsStats;
    const Layout                 = Searchkit.Layout;
    const LayoutBody             = Searchkit.LayoutBody;
    const LayoutResults          = Searchkit.LayoutResults;
    const SearchBox              = Searchkit.SearchBox;
    const TopBar                 = Searchkit.TopBar;
    const SideBar                = Searchkit.SideBar;
    const ActionBar              = Searchkit.ActionBar;
    const ActionBarRow           = Searchkit.ActionBarRow;
    const HierarchicalMenuFilter = Searchkit.HierarchicalMenuFilter;
    const RefinementListFilter   = Searchkit.RefinementListFilter;
    const SelectedFilters        = Searchkit.SelectedFilters;
    const ResetFilters           = Searchkit.ResetFilters;
    const MovieHitsGridItem      = Searchkit.MovieHitsGridItem;

    return (<div>
      <SearchkitProvider searchkit={sk}>
        <Layout>
          <TopBar>
            <SearchBox autofocus={true} searchOnChange={true} prefixQueryFields={["actors^1","type^2","languages","title^10"]}/>
          </TopBar>
          <LayoutBody>
            <SideBar>
              <HierarchicalMenuFilter fields={["type.raw", "genres.raw"]} title="Categories" id="categories"/>
              <RefinementListFilter id="actors" title="Actors" field="actors.raw" operator="AND" size={10}/>
            </SideBar>
            <LayoutResults>
              <ActionBar>
                <ActionBarRow>
                  <HitsStats/>
                </ActionBarRow>
                <ActionBarRow>
                  <SelectedFilters/>
                  <ResetFilters/>
                </ActionBarRow>
              </ActionBar>
              <Hits mod="sk-hits-grid" hitsPerPage={10} itemComponent={MovieHitsGridItem} sourceFilter={["title", "poster", "imdbId"]}/>
              <NoHits/>
            </LayoutResults>
          </LayoutBody>
        </Layout>
      </SearchkitProvider>
    </div>);
  }
});

React 相当新,所以不太清楚为什么会出现这些问题?

谢谢

【问题讨论】:

  • 不确定这是否导致问题,但请注意;我不会在渲染范围内声明这些常量。我建议将它们移至全局范围,或者您甚至可以在返回 JSX 中引用这些项目的完整路径(例如 &lt;SearchKit.SearchkitProvider serachkit={sk}&gt;

标签: ruby-on-rails ruby reactjs


【解决方案1】:

好的,我刚刚浏览了这个 searchkit 库。基于它是一个 React 组件并且您使用的是 react-rails 的事实,我几乎可以肯定您遇到了一次拥有两个 React 实例的问题。 react-rails 缺点是很难与它集成外部库。设置和开始使用很快,但是一旦你想安装其他反应库,你就会碰壁。

我之前遇到过这个问题,我所做的是改用https://github.com/netguru/react_webpack_rails。如果您想要更多东西,请查看https://github.com/shakacode/react_on_rails。如果您认真对待 React 及其生态系统,这两个选项需要更多的努力来设置,但非常值得。

顺便说一句:Searchkit 看起来很棒!

【讨论】:

    【解决方案2】:

    我似乎要迟到了,但以防万一,有人可能会再次遇到此问题并需要更直接的解决方案。

    供您参考:

    • Rails 5.2.0
    • Ruby 2.5.1p57(2018-03-29 修订版 63029)[x86_64-darwin17]
    • React-rails (2.3.1)

    我相信这也可能发生在不同的 rails 和 ruby​​ 版本上。

    就像@kasperite 所说的那样,我确定您错误地拥有了两个 React 实例。您要么是'require react' 两次,要么是通过'application.js' 文件中的'require_tree .' 进入双重实例​​。

    更具体地说,您应该检查'application.js' 文件中的以下几行:

    //= require react
    //= require react_ujs
    //= require components
    //= require_tree .
    

    问题是您首先通过 require react 指令加载 React,然后使用 require_tree . 指令再次加载它。

    参考:https://guides.rubyonrails.org/asset_pipeline.html#manifest-files-and-directives

    或者直接引用上面链接中的官方指南

    require_tree 指令告诉 Sprockets 递归地将指定目录中的所有 JavaScript 文件包含到输出中。这些路径必须相对于清单文件指定。您还可以使用 require_directory 指令,该指令仅包含指定目录中的所有 JavaScript 文件,无需递归。

    要对问题进行排序,您只需完全删除 require_tree . 指令或通过删除等号取消设置 - 将此 //= require_tree . 转为 // require_tree .

    希望这个帮助和欢呼。

    【讨论】:

      猜你喜欢
      • 2017-04-03
      • 2017-03-14
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多