I'm updating the dependencies of my React project (react router 4, react-router-redux 5 alpha).
My code looks like this:
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<HashRouter>
<div>
<Switch>
<Route path='/report-type/:reportType/:rootAddress' component={App}/>
<Route component={App}/>
</Switch>
</div>
</HashRouter>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
)
it works fine on my local machine but fails to do the routing on the server. I can see that the action ##router/LOCATION_CHANGE fails to update the routing key in the next state. I get location: null which should be an object instead.
What could be the difference between the two environment that prevents it from working on the server?
Related
I have need to redirect a user outside of a React component, which typically is done using history with react-router.
// history.js
const history = createBrowserHistory();
export default history;
// App, setting up router
import { HashRouter as Router } from 'react-router-dom';
import history from './history';
...
<HashRouter history={history}>...</HashRouter> // problem
// Non-component file
import history from './history';
history.push('/target');
Since HashRouter doesn't take a history prop, but rather handles history internally, and developers are directed to use withRouter in order to expose history to a component, it's not apparent how to do redirects outside of a component.
I am using HashRouter and I need to use the history outside of a component (meaning I can't use withRouter).
How could I make this happen?
Yes, there is a way to use history and a hash-based router together.
When creating a history instance, use createHashHistory instead of createBrowserHistory.
// myCreatedHistory.js
import { createHashHistory } from 'history';
export default createHashHistory();
Instead of using HashRouter, use the low-level Router instead, and pass the history props to it, like so.
// App
import { Router } from 'react-router-dom';
import history from '../myCreatedHistory';
...
<Router basename="/" history={history}>...</Router>
Then you can import the history from anywhere (say a middleware).
// Middleware, or anywhere
import history from '../myCreatedHistory';
history.push('/target');
I'm loving v4 but in 4.1.2 this keeps tripping me up when using the browser router:
With a component in a Route component I have these props passed in: {computedMatch, location, path} although the documentation tells me to expect {match, location, history} which is what I get with the hash router.
To get the history passed in I have to use the withRouter wrapper which feels very clunky because the relevant component is the component prop to a Route component.
The documentation sounds right to me. Is this a bug?
You can get access to {match, location, history} if you use Route as
<Route path="/" component={myComponent}
In above code you will have match location and history accessible inside myComponent.
Or else you have to use withRouter
I am creating a blog using React/React-Router/Redux, and depending on the location, I want to show different blog posts, so if you are on /category/cat1 you don't have the same list of blogs than if you are on /category/cat2.
So I'm thinking on storing the blog list in the store and my react component would pick it up from there so I could just have actions updating my state.
My thinking is listening on the browserHistory so I can get when the location changes and trigger the action which would update the new blog list, but I can't find how to get the params from my location path like I would from my component props /category/:catName
How can I get those params?
Is it actually the way to do it or should I use a different approach?
Thanks.
From the version 2.0.0 upgrade guide:
RoutingContext -> Router render prop
You can now pass a render prop to Router for it to use for rendering.
This allows you to create "middleware components" that participate in
routing. Its critical for integrations with libraries like Relay,
Redux, Resolver, Transmit, Async Props, etc.
The default is basically this:
<Router render={props => <RouterContext {...props} />} />
This render prop on the Router is a hook into the render stage, and those props that are passed to the function contain the parsed route params, as well as lots of other routing context. Just make sure your function returns a RouterContext, or some equivalent, in the end.
I'm using react-router 1.0.3. Say I define these routes
<Route path="/" component={App} onEnter={appOnEnter}>
<Route path="test" component={Test} onEnter={testOnEnter} />
</Route>
Both appOnEnter and testOnEnter are asynchronous functions. By default testOnEnter waits for appOnEnter to finish and call the callback to run, but I want those 2 onEnter functions to run simultaneously, how can I do that?
This won't work with the react-router 1.0.3. I checked the source-code of it and don't see a way to call both hooks at the same time.
Here is a reference to the onEnter-Hook handling, if you might want to take a deeper look into it: https://github.com/rackt/react-router/blob/v1.0.3/modules/TransitionUtils.js
Maybe you can find a way to trick the system...
But I also would not recommend doing it. I don't have an idea of what you want to achieve but I think you should find a different approach, using other life-cycle hooks that react provides.
I have taken the simple activemq-camel-blueprint example from ServiceMix 4.4.0, and added in a Mina TCP socket to read from ASCII lines.
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="mina:tcp://localhost:4001?textline=true&sync=false" />
<bean ref="NMEAString" method="ingest" />
<to uri="activemq:queue:LOG.ME"/>
</route>
<route>
<from uri="activemq:queue:LOG.ME" />
<to uri="log:ExampleActiveMQRouterBlueprint" />
</route>
</camelContext>
I am running the example within Karaf. All the NMEAString does is print out the object to STDOUT.
I run a little program to push an ASCII file to a socket connection. It pushes in the whole file (~40) lines in a few milliseconds.
I see a STDOUT printout within Karaf at about 30 seconds between lines.
I am getting the following exceptions within my servicemix.log file:
Does anyone know what this exception means and why it is throwing it with such a simple
example?
org.apache.camel.CamelException: org.apache.camel.CamelExchangeException: Cannot write body. Exchange[Message: [Body is null]]
at org.apache.camel.component.mina.MinaConsumer$ReceiveHandler.exceptionCaught(MinaConsumer.java:91)[186:org.apache.camel.camel-mina:2.8.3]
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.exceptionCaught(AbstractIoFilterChain.java:564)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain.callNextExceptionCaught(AbstractIoFilterChain.java:345)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain.access$1000(AbstractIoFilterChain.java:53)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.exceptionCaught(AbstractIoFilterChain.java:643)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:224)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:264)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)[:1.6.0_29]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)[:1.6.0_29]
at java.lang.Thread.run(Thread.java:662)[:1.6.0_29]
Caused by: org.apache.camel.CamelExchangeException: Cannot write body. Exchange[Message: [Body is null]]
at org.apache.camel.component.mina.MinaHelper.writeBody(MinaHelper.java:55)[186:org.apache.camel.camel-mina:2.8.3]
at org.apache.camel.component.mina.MinaConsumer$ReceiveHandler.messageReceived(MinaConsumer.java:148)[186:org.apache.camel.camel-mina:2.8.3]
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:220)[187:org.apache.servicemix.bundles.mina:1.1.7.5]
... 4 more
L.S.,
Just tried this myself with Apache ServiceMix 4.4.0 and the blueprint file below works fine for me, so I suspect that your bean somehow invalidates or removes the message body (e.g. by calling getOut() on the Exchange and creating an empty message or something like that).
Could you try removing the bean from your route to ensure that it is really the cause of the problem? If it is, feel free to post the code of the bean itself and we can help you look for the problem that's lurking in there...
Regards,
Gert
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="mina:tcp://localhost:4001?textline=true&sync=false" />
<to uri="log:test-read-stream"/>
<to uri="activemq:queue:LOG.ME"/>
</route>
<route>
<from uri="activemq:queue:LOG.ME" />
<to uri="log:ExampleActiveMQRouterBlueprint" />
</route>
</camelContext>
</blueprint>