0

I am trying to build a simple application with Ruby on Rails and React. I am using a gem react_on_rails. In addition, I am trying to use Redux to communicate between different components when I need. The issue that I having at the current moment I don't understand how to hold Store in the application. If it a plain React app, I don't have a problem to share the Redux between components. In React On Rails is a different way to setup it and it works fine at current implementation, but I am losing the store when I switching to a different page or refreshing the page.

My goal is to add the product ID to the cart via Redux and them when user redirects to the /cart page it can retrieve the cart array from Redux store and then I can populate the page with needed products.

Example of simple view component in Rails.

<div class='fancyClass'>
  <%= react_component("ProductDetail", props: {product: @product.id}) %>
</div>

Example of simple react component which adding a product to the cart array

// @flow

import * as React from 'react';
import { Provider, connect } from 'react-redux';
import { setCart } from 'action/SetCart';
import { createStore } from 'redux';
import rootReducer from '../reducers';

const store = createStore(rootReducer);

type Props = {
    product: number
}

export class Scratch1 extends React.Component<Props> {
    onClick = () => {
        this.props.setCart(this.props.product);
        window.location.assign('/cart')
    };

    render() {
        return (
            <Provider store={store}>
                <button onClick={this.onClick}>add to cart</button>
            </Provider>
        );
    }
}

const Scratch1Redux = connect(
    state => ({
        cart: state.cart,
    }),
    dispatch => ({
        setCart: id => {
            dispatch(setCart(id))
        }
    })
)(Scratch1);

export default Scratch1Redux;

Thank you in advance

GYTO
  • 440
  • 1
  • 10
  • 23

1 Answers1

1

You're not understanding how React + Rails works. Rails serves assets: HTML, JS + React, CSS. Every time your make a new request to a new route, React is technically going to be shipped along with all of your components and a new store will be mounted. If you want to have your store persist, you must allow your app to route like a Single Page Application (SPA).

If you'd like your Cart to persist, try and create a Cart object in your database and give a User a cart. That way, it would persist indefinitely. You can pass your Cart data to the user via a JSON object in an HTML data tag or a JSON API request in React (preferable)

Your question is basically dealing with this: This seems like a duplicate of https://stackoverflow.com/a/3433048/8844929

Veridian Dynamics
  • 1,405
  • 1
  • 9
  • 19
  • this is something that I want to avoid in my app by storing a cart in my database and do it with Redux to store all user carts in their browsers, not in the database which I am limit to the size that I have on it. React on Rails has a helper `<%= react_store('rootStore') %>` which actually can handle the store between pages, but it doesn't really work for me right now. – GYTO Mar 19 '19 at 15:57
  • I believe it is `redux_store`, not `react_store`. Use `redux_store(store_name, props)` to create a fresh version of the store (because it may already exist if you came from visiting a previous page). Note: for this example, since we're initializing this from the main layout, we're using a generic name of @react_props. The Rails controller would set @react_props to the properties to hydrate the Redux store. In other words, you're supposed to pass the data @react_props from the controller. Its that same process I described above with the `redux_store` to make rehydrating your store easier. – Veridian Dynamics Mar 19 '19 at 16:19
  • Ok. To fully understand what I just read. If I want to have shared store between the components which are in different pages I can use ‘redux_store’ to communicate between props that I saved in the store. In other words this is a way to make my application persist with redux store when I changing the page? – GYTO Mar 19 '19 at 16:25
  • Yes. If you have a store with data "{ name: GTYO }" and you want that data to exist on another page with the same store (eg. it initializes as "{ name: undefined }", then your controller needs to pass down: `@react_props = { name: "GTYO" }.to_json` and then you need to perform redux_store on that store name with your `@react_props`. Some more configuration might be required. Just read this section of the read_me: https://github.com/shakacode/react_on_rails/blob/master/docs/api/redux-store-api.md#controller-extension – Veridian Dynamics Mar 19 '19 at 16:30