I am trying to use react-router 2.X to include a redirect logic.
<Route path="albums" component={AlbumList}>
<Redirect from=":albumId" to='/photos/' query= { {'album_id': ':albumId'} } />
</Route>
it seems like :albumId can be extracted from the url in "from" and "to" properties but not in query, how can I use the value of :albumId in query property. Thanks
Related
My use case is to have a universal page view statistic function for react-router v4, so it may looks like:
<Provider store={store}>
<Router>
<Tracker>
<App />
</Tracker>
</Router>
</Provider>
My advanced requirement is to get all params from route, so a URL of /users/kitty/books/199231 can be parsed to:
{
path: '/users/:username/books/:isbn',
params: {
username: 'kitty',
isbn: '199231'
}
}
The problem is, my Tracker component can never get access to a nested route's path and match prop, even if I use withRouter with my Tracker component, it gets a path of /
I know in theory my requirement is not correct because we can put two or more <Router> side by side by side, so my real case would be "get the deepest route's params"
Is it possible to archive this? or is there any solution that my page view statistics can parse a URL to it's corresponding route path and params?
After checking out this react-router tutorial, I tried to integrate what I learned here into my project.
My scenario is similar to the number 2 from the tutorial, except that when the user enters /, I want to fetch an api and redirect to the first category comming from the api that looks like this [{'category':'electronics', 'items':[{..}],..},..]
my router looks like this
import RoutaZ from 'Routes.js';
...
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRedirect to={RoutaZ.state.data[0].name} />
<Route path=":category" components={Container, SideNavigation} />
</Route>
my Routes.js looks like this
let Routes = React.createClass({
getInitialState () {
return {
data: null
}
},
componentDidMount() {
var self = this;
fetchData().then(function(results){
self.setState({data: results.data});
})
},
render() {
/* want to return the the first category from api */
return this.state.data[0].name
}
});
In the router, RoutaZ.state.data[0].name returns undefined because the initial state is null. If I set the initial state to [{'category':'hello',...}], it returns hello and redirects to the hello page as expected. What can I do to redirect after the db is fetched?
1) How can I use onEnter from react-router with my current config?
2) How and where can I set a parent component to my router handle all the fetching and pass it to the router as a child?
EDIT: This is just a little part of my application,which is finished but I only have this redirect issue. I know that I can use redux-saga but all my application is already done and would have to redo it completely which I cannot afford.
1- I tried using onEnter but don't know where I should place it.
2-Somewhere in my application is fetched data from the parent component and gave it as props to the child and the child received the data from the api.
Solved it. I had to push the results when the component mounted
componentDidMount() {
var self = this;
fetchData().then(function(results){
router.push(results.data[0].category);
})
},
Assuming my app's base url is example.com/app
Is it possible to set a base route in react-router so instead of writing all routes as
/app/a
/app/b
/app/c
I can just specify them as
a
b
c
I tried the below example I found in the docs but it wouldn't work (page would display nothing). Maybe it's because I'm using react-router#3.0.0-alpha.1, or I'm doing something wrong.
import { useRouterHistory } from 'react-router'
import { createHistory } from 'history'
const history = useRouterHistory(createHistory)({
basename: '/app'
})
const Root = ({store}) => (
<Provider store={store}>
<Router history={history}>
<Route path='/' component={App}>
...
</Route>
</Router>
</Provider>
)
With the newest react router (v4) you can easily do this
<BrowserRouter basename="/calendar">
<Link to="/today"/> // renders <a href="/calendar/today">
</BrowserRouter>
If you want to use <Router />, that give you access to history object, allowing you to change page through history.push('/my-path') method directly from js. You will face the issue that BrowserRouter does not have history prop available, and Router does not have basename available.
The solution is the following:
const App: React.FC = () => {
// do not put a slash at the end of the basename value.
const history = createBrowserHistory({ basename: '/your-base-name' });
return <Router history={history}>
...
</Router>;
}
The base URL for all locations. If your app is served from a sub-directory on your server, you’ll want to set this to the sub-directory. A properly formatted basename should have a leading slash, but no trailing slash
https://reacttraining.com/react-router/web/api/BrowserRouter/basename-string
I have a legacy web app that is being replaced with React and it is called by these various systems by being passed a URL (derived from records in and existing DB system) The app renders folder views, of files in a sandboxed container according to the path passed in.
I need to be able to identify these requests and route them to a File/Folder handing page, treating everything after the '/files/ part of the path down as a parameter to the path of the file or folder.
<Route path="/" handler={Master}>
<Route name="files_link" path="files" handler={Files} />
<Route name="filesWithPath_link" path="files/*:path" handler={Files} />
</Route>
I would like to be able to handle requests passed into
/files
and have it handled in the page (defaulting to top level folder because no path parameter passed.
and have all the following examples of possible URL just passed to the router and extract the path parameter from the bit after /files/.
/files/folder path=folder
/files/folder/filename.ext path=folder/filename.ext
/files/folder/folder1 path=folder/folder1
/files/folder/folder1/filename.ext path=folder/folder1/filename.ext
/files/folder/folder1/folder2/ path=folder/folder1/folder2
/files/folder/folder1/folder2/filename.ext path=folder/folder1/folder2/filename.ext
.... and so on ...
When I try this I get an error
Uncaught Invariant Violation: Missing "splat" parameter for path "/beta/page/files/*:path"
I'm currently using react 0.14.2 and react-router 0.13.4.
How would you go about handling a variable length path in this manner in React-router?
You need to use it like so:
<Route name="filesWithPath_link" path="files/*" handler={Files} />
And then in your React component you can access the value of the splat:
// The '*' in the path match gets assigned to this.props.params.splat
var path = this.props.params.splat;
For completeness, the splat parameter can be accessed from the useParams() hook as property 0:
const splat = useParams()[0];
In React Router v6, the "*" can be accessed from useParams() as a property named *.
const wildcard = useParams()["*"];
And of course you can always get the entire URL (i.e. everything including the bit before the *) using useLocation()
Example in TypeScript with a named parameter:
<Route path="/files/:path">
<Files/>
</Route>
import { useParams } from 'react-router';
export function Files(): React.ReactElement {
const splat = useParams<{ path: string }>().path;
}
"react-router": "^1.0.2"
Here is the Redirect Route:
javascript
<Redirect from="/organize/folder(/:id)" to="/organize/(:id)" />
Where id is of shape someUser:88
So given URL:
http://localhost/organize/folder/someUser:88
We would expect the redirect to take us to:
http://localhost/organize/someUser:88
But instead, it seems that the : is being query string parsed, and instead we end up with:
http://localhost/organize/someUser%3A88
So the parsed string works, but previous versions of react-router would maintain the un-parsed id and pass that to the redirect.
Is there something I may be missing? Perhaps a config option to not auto parse params? I tried with other characters other than :, for example ~, and all the others seem to work.
Perhaps it is somewhere that react-router is parsing for the : for the param and it ends up parsing all of them?
Thanks in advance.
colon is used for parsing variable.
Here is my solution:
function enterIndex(nextState, replace) {
replace('/folder/someUser:88');
}
...
<IndexRoute onEnter={ enterIndex } />
...
or
<Route path="folder/:id" onEnter={ enterIndex } />
Hope it could help you.