1

I've just installed a fresh react into my rails project with 'React-rails' and added searchkit on top of it. But I'm getting some errors with it.

Uncaught Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded.

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>);
  }
});

Fairly new with React, so not too sure why these problems are occuring?

Thanks

Community
  • 1
  • 1
Jonathan
  • 673
  • 1
  • 10
  • 32
  • Not sure if this is causing the problem or not, but a note; I wouldn't declare those consts within the render scope. I would suggest moving those to the global scope, or you can even just reference the full path to those items in the return JSX (e.g. ``) – Jake Haller-Roby Jun 06 '16 at 17:47

2 Answers2

1

Ok, I just browsed through this searchkit library. Based on the fact it's a React component and you are using react-rails, I'm almost certain you are running into the issue of having two React instances at one time. react-rails drawback is the difficulty to integrate external libraries with it. It's quick to setup and start using but as soon as you want to install other react libraries, you will hit a wall.

I had this issue before and what I did was to use https://github.com/netguru/react_webpack_rails instead. If you want something abit more then have a look at https://github.com/shakacode/react_on_rails. These two options require more effort to setup but well worth it if you are serious about React and its ecosystem.

BTW: Searchkit looks great!

kasperite
  • 2,460
  • 1
  • 15
  • 17
1

It seems I'm about late for the party but, just in case, someone may experience this issue again and need a more direct solution.

For your reference:

I believe this could happen on different rails and ruby versions too.

As like what @kasperite said, I'm sure you are having two React instances by mistake. You are either 'require react' twice or running into the dual instances by the 'require_tree .' in the 'application.js' file.

To be more specific, you should check the following lines in the 'application.js' file:

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

The issue is that you first load React by require react directive, then load it again using the require_tree . directive.

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

Or direct quote from the official guide as in the above link

The require_tree directive tells Sprockets to recursively include all JavaScript files in the specified directory into the output. These paths must be specified relative to the manifest file. You can also use the require_directory directive which includes all JavaScript files only in the directory specified, without recursion.

To sort the issue, you just need to completely delete the require_tree . directive or unset it by removing the equal sign - turn this //= require_tree . to // require_tree .

Hope this help and cheers.

vchar
  • 956
  • 1
  • 11
  • 15