Reputation: 5220
I am still quite confused about data flow in React / Redux build. I am fairly comfortable when working "in" my app but I can't figure out how to pass data to my app from server?
I have react-app.php file with article#main-content
element which is base element for my app. I want to pass the element information about some product.
How do I do that?
I wanted to give article#main-content
prop productName but I don't know how to access it from react.
My guess is from reducer ... but how? Maybe I should not relly on article#main-content
and pass variables to react in $_GET
parameters?
react-app.php
<link rel="stylesheet" type="text/css" href="/lines-configurator/build/style.css" media="screen"/>
<script async type="text/javascript" src="/lines-configurator/build/bundle.js"></script>
<article id="main-content" productName="My Product">
</article>
App.js:
import React from 'react';
import {render} from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reducer from './reducers/index';
import BoardConfig from './containers/BoardConfigContainer';
import BoardProduct from './containers/BoardProductContainer';
const store = createStore(reducer, window.devToolsExtension && window.devToolsExtension());
render(
<Provider store={store}>
<div>
<BoardConfig />
<BoardProduct />
</div>
</Provider>,
document.getElementById('main-content')
);
BoardProductContainer.js
import {connect} from 'react-redux';
import BoardProduct from '../components/BoardProductComponent';
export default connect(
function mapStateToProps(state) {
return {
};
},
function mapDispatchToProps(dispatch) {
return {};
}
)(BoardProduct);
BoardProductComponent.js
import React from 'react';
export default function () {
return ();
}
BoardProductReducer.js
import * as types from '../constants/constants';
import Immutable from 'immutable';
const initialState = Immutable.Map({});
export default function boardReducer(state = initialState, action) {
switch (action.type) {
default:
return state;
}
}
Upvotes: 0
Views: 1302
Reputation: 1377
I do this differently. I define global javaScript variables in the html head when I am rendering my page in php - I am using a blade template, so mine looks like this:
var orgUnitIdGlobal = {!! json_encode($orgUnitId, JSON_FORCE_OBJECT) !!};
Then in my app.js I can call on that variable:
var elementId = 'appRoot';
if (document.getElementById(elementId)) {
let store = createStore(reducer,{
orgUnitId : orgUnitIdGlobal
});
ReactDOM.render(
<Provider store={store}>
<MyComponent />
</Provider>,
document.getElementById(elementId)
)
}
the 'orgUnitId' is then passed through to my reducer:
import orgUnitId from './orgUnitId.js'
...other reducers for other parts of the state...
export default combineReducers({
orgUnitId,
...other reducers....
})
and as i pass {orgUnitId: orgUnitIdGlobal} as the second parameter to my createStore, it is passed through as the state in the call to the orgUnitId(state,action) when the component is being initialised.
I can then refer to that value (I think) from other reducers, and make what ever API calls I need - like api.com/getname?orgUnitId=7 in the getName reducer.....
Upvotes: 1
Reputation: 100331
You can get url parameters from
this.props.location.query
Ex:
// http://localhost:3000/?test=1
console.log(this.props.location.query);
/*
{
test: "1"
}
*/
Normally you would call and action that makes an ajax request and return in the reducer.
But since you already have a value since the beginning what you can do is wrap the code of your App.js in a start
function
export default function start(serverVar) {
// use serverVar here:
const store = createStore(reducer, window.devToolsExtension && window.devToolsExtension());
render(
<Provider store={store}>
<div>
<BoardConfig />
<BoardProduct />
</div>
</Provider>,
document.getElementById('main-content')
);
}
Change your webpack's output to include:
library: 'Foo'
On your html file add:
<script type="text/javascript">
Foo.start('<?php echo $serverVar; ?>');
</script>
Ignore all the setup above and just do this
<script type="text/javascript">
window.someValue = '<?php echo $serverVar; ?>';
</script>
Upvotes: 2
Reputation: 1021
I would normally create an action, with the following flow:
Dispatch event { type: GETTING_DATA, status: IN_PROGRESS }. Now based on this, the reducer could modify the state such that you can display a spinner or whatever element you prefer, to let the user know data is loading.
Perform AJAX request to the server and get the data.
a) Dispatch event { type: GETTING_DATA, status: SUCCESS } if the data was retrieved successfully. The reducer can now update the state and your component will re-render.
b) Dispatch event { type: GETTING_DATA, status: FAILED } if there was a problem while retrieving data. The reducer can now modify the state in such a way that the user knows some error occurred.
Hope that helps!
Upvotes: 1