I am developing an app based in this React Redux boilerplate.
In one ponent I need to get the current URL when ponent is mounted in order to generate a shareable URL for social media. Than ponent is being accesible from dynamically generated URLs with React Router. In client side I wouldn't have any problem by getting it through javascript document
object but the problem lies server side.
I thought about making available in the Redux store the Node.js environment data kept in this config.js
file, where hostname is kept
// Node.js environment file config.js
require('babel-polyfill');
const environment = {
development: {
isProduction: false
},
production: {
isProduction: true
}
}[process.env.NODE_ENV || 'development'];
module.exports = Object.assign({
host: process.env.HOST || 'localhost',
port: process.env.PORT,
apiHost: process.env.APIHOST || 'localhost',
apiPort: process.env.APIPORT
}, environment);
and with the location
object of React Router set as props in the ponent get the pathname and fully construct the URL.
What I have done is to create a simple reducer with an initial state to keep the Node.js config enviroment data and just the default action to include in my bineReducers
function with the other app reducers.
const initialState = {
config: {}
};
export default function config(state = initialState, action = {}) {
switch (action.type) {
default:
return state;
}
}
And then I injected the Node.js object with the environment data in the creation of the store, as initial state data, in my server.js
file.
import config from './config';
...
const store = createStore(memoryHistory, client, {config});
...
Thus I have available the hostname and I am able in the ponent to construct its full url both client and server side through Redux store.
But, is there any simpler / cleanest way? I am afraid I might be overkilling it or creating any security issue to my app.
I am developing an app based in this React Redux boilerplate.
In one ponent I need to get the current URL when ponent is mounted in order to generate a shareable URL for social media. Than ponent is being accesible from dynamically generated URLs with React Router. In client side I wouldn't have any problem by getting it through javascript document
object but the problem lies server side.
I thought about making available in the Redux store the Node.js environment data kept in this config.js
file, where hostname is kept
// Node.js environment file config.js
require('babel-polyfill');
const environment = {
development: {
isProduction: false
},
production: {
isProduction: true
}
}[process.env.NODE_ENV || 'development'];
module.exports = Object.assign({
host: process.env.HOST || 'localhost',
port: process.env.PORT,
apiHost: process.env.APIHOST || 'localhost',
apiPort: process.env.APIPORT
}, environment);
and with the location
object of React Router set as props in the ponent get the pathname and fully construct the URL.
What I have done is to create a simple reducer with an initial state to keep the Node.js config enviroment data and just the default action to include in my bineReducers
function with the other app reducers.
const initialState = {
config: {}
};
export default function config(state = initialState, action = {}) {
switch (action.type) {
default:
return state;
}
}
And then I injected the Node.js object with the environment data in the creation of the store, as initial state data, in my server.js
file.
import config from './config';
...
const store = createStore(memoryHistory, client, {config});
...
Thus I have available the hostname and I am able in the ponent to construct its full url both client and server side through Redux store.
But, is there any simpler / cleanest way? I am afraid I might be overkilling it or creating any security issue to my app.
Share Improve this question edited Feb 13, 2018 at 15:20 Dez asked Mar 9, 2017 at 13:16 DezDez 5,8488 gold badges46 silver badges52 bronze badges1 Answer
Reset to default 2I was having this issue when attempting to use Helmet server-side. I passed in the request as a prop to my main <App>
ponent and then use either that request object (server-side) or the window object (client-side).
App.js
render() {
// Get full url from client or server
let fullURL = ''
if(typeof window !== 'undefined'){
fullURL = window.location.protocol + '//' + window.location.host + this.props.location.pathname
}else if(this.props.serverRequest){
fullURL = this.props.serverRequest.headers.host + '/' + this.props.location.pathname
}
const urlTag = fullURL === '' ? null : <meta property="og:url" content={fullURL} />
const linkTag = fullURL === '' ? null : <link rel="canonical" href={fullURL} />
const helmet = this.props.siteInfo.site
? <Helmet>
<title>{this.props.siteInfo.site.title}</title>
<meta property="twitter:title" content={this.props.siteInfo.site.title} />
{urlTag}
{linkTag}
<meta property="og:type" content="website" />
</Helmet>
: null
return (
<div>
{helmet}
<Notices />
<div className="body">
<Header />
<Body />
</div>
<Footer />
</div>
)
}
server.js
const markup = renderToString(
<Provider store={store}>
<StaticRouter location={req.url} context={context}>
<App serverRequest={req} />
</StaticRouter>
</Provider>
)
const helmet = Helmet.renderStatic()
Is this "proper" or "best practice"? No idea, but it works well and is easy to follow :)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744725956a4590177.html
评论列表(0条)