Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you hydrate a store using react_on_rails' Redux API?

Currently, I'm working with this setup (simplified for readability):

react_on_rails 11.1.4

Layout Controller (index method):

redux_store('appStore', props: { foo: 'bar' })

Layout:

<%= redux_store_hydration_data %> (before close of body tag)

View:

<%= react_component('FooBar') %>

Component (FooBar):

ReactOnRails.getStore('appStore');

JavaScript (main.js):

ReactOnRails.registerStore({ appStore });

If I inspect the source, the data and the component appear to be present:

<div id="FooBar-react-component-fb8d03cb-b3d3-4247-8b4b-3e5a2ad52f84"></div>
<script type="application/json" class="js-react-on-rails-component" data-component-name="FooBar" data-trace="true" data-dom-id="FooBar-react-component-fb8d03cb-b3d3-4247-8b4b-3e5a2ad52f84">{}</script>
<script src="/main.js"></script>
<script type="application/json" data-js-react-on-rails-store="appStore">{"foo":"bar"}</script>

However, the component itself isn't rendering due to these fatal errors:

Uncaught Error: There are no stores hydrated and you are requesting the store appStore...`
Uncaught Error: Could not find store registered with name 'appStore'. Registered store names include...

So far as I can tell, the setup is inline with what's been outlined in the documentation, so I'm wondering if this is a bug of some sort. I've tried putting the call to redux_store in both the controller and the view, moving the other calls into other files and locations, etc. to no avail.

Any help is much appreciated, thanks in advance!

like image 538
robbymarston Avatar asked Mar 09 '26 17:03

robbymarston


1 Answers

I had the exact same problem. This is how I solved it. Initially, I had this

const appStore = ReactOnRails.getStore("myStore");

const HelloWorldApp = (appStore) => (
    <Provider store={appStore}>
        <HelloWorldContainer />
     </Provider>
);

export default HelloWorldApp;

But it was failing to register the store here

const appStore = ReactOnRails.getStore("myStore");

So I changed it to this

import React from 'react';
import { Provider } from 'react-redux';
import HelloWorldContainer from './HelloWorldContainer';

const HelloWorldApp = (props) => (
    <Provider store={ReactOnRails.getStore("myStore")}>
        <HelloWorldContainer />
    </Provider>
);

export default HelloWorldApp;

The "There are no stores hydrated" thing is a bit misleading. A "hydrated" store, is just a populated object. When you viewed your html you did have a hydrated store it just wasn't found by the JS. I believe by adding ReactOnRails.getStore in here

<Provider store={ReactOnRails.getStore("myStore")}>

helps with the load order. I believe the reason it wasn't initially working for me is because of the JS load order. I hope this helps someone.

like image 157
Harry Fairbanks Avatar answered Mar 11 '26 05:03

Harry Fairbanks



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!