kobe
kobe

Reputation: 15835

Isomorphic react redux sending Dynamic Id

I am using react router with redux for isomorphic app. I have an use case where href needs to work both on client and server side. This is mainly for SEO reasons. for bots it should use href and when user clicks it should work too

my route looks like this

 <Route name="app" component={ProductPage} path="/product/:Id">
      <IndexRoute component={ProductContainer}/>
  </Route>

http://localhost:3000/product/1234 (this works from server side)

Once the above URL renders data, i have page with different URLS of that kind

http://localhost:3000/product/3456
http://localhost:3000/product/9999

when user clicks the above URLS, i don't want to do a post back, i want to use browserHistory api and render the component, is it possible?

I have this in the container

static needs = [
    productActions.getProductData
  ]

Any direction will be appreicated

Upvotes: 0

Views: 279

Answers (1)

jacoballenwood
jacoballenwood

Reputation: 3057

Server Side

You could require a function call that would do your dispatches onEnter of the specific route, which would populate the app state that you need to render your component.

the route would look something like this:

<Route component={ProductPage} path="/product/:Id" onEnter={requireProductData} />

requireProductData would be a function in your main.js something like this:

function requireProductData(nextState, replace, callback) {
    const { params } = nextState
    var idNum = parseInt(params.id.toString().split("-")[0])
    const currentState = store.getState()
    if (idNum > 0) {
        store.dispatch(ProductActionCreators.productInfo({ id: idNum })).then((event) => {
           callback()
        }, (error) => {
           callback()
        })
    } else {
        callback()
    }
}

this would do your action creator calls and then your reducer would take care of the app state. then you could render your component from that url.

Client Side

Yeah, you're right about doing an onClick handler. Here's an example of where clicking a button causes an API call with a dispatch:

class SubscribeUserDialog extends Component {

    subscribeUser(privacy) {
        const { dispatch, readingPlan, auth } = this.props
        if (!auth.isLoggedIn) window.location.replace(`/sign-in`)
        // if user isn't subscribed, then subscribe!
        if (!readingPlan.subscription_id) {
            dispatch(ActionCreators.readingplanSubscribeUser({ id: readingPlan.id , private: privacy }, auth.isLoggedIn)).then(() => {
                // redirect to plan
                this.goToPlan()
            })
        } else {
            // user already subscribed
            this.goToPlan()
        }
    }



    render() {

        return (
            <div className='plan-privacy-buttons text-center'>
                <p className='detail-text'><FormattedMessage id="plans.privacy.visible to friends?" /></p>
                <div className='yes-no-buttons'>
                    <a className='yes solid-button green' onClick={this.subscribeUser.bind(this, false)}><FormattedMessage id="ui.yes button"/></a>
                    <a className='no solid-button gray' onClick={this.subscribeUser.bind(this, true)}><FormattedMessage id="ui.no button" /></a>
                </div>
            </div>
        )
    }
}

export default SubscribeUserDialog

In your case, you would have the onClick attached to your links.

Does this help you?

Upvotes: 1

Related Questions