问题
I am trying to migrate my website from traditional web app approach to react based app. In this process I am stuck with a problem related to urls. In my website, on server side I use Url Rewrite feature to map urls to their correct controller. But I am not able to figure out how to handle this thing in react router. My current, react router code looks like this
<BrowserRouter>
<Route exact path="/" component={Home}/>
<Route path="/black-forest" component={Product}/>
<Route path="/cakes" component={ProductList}/>
</BrowserRouter>
This code I have written for building a prototype. But ideally there are many different urls which can point to ProductList component. Similarly there are many urls which can point to Product component.
For e.g,
Following urls points to ProductList component
- http://www.example.com/best-cakes-in-australia
- http://www.example.com/cake-delivery-in-india
- http://www.example.com/flowers-delivery-in-canada
At a gross level I have around 10,000 such urls which are created using server side UrlRewrite hence they follow no specific pattern. These url are mostly going to point towards either ProductList or Product component.
How can I create path for all these urls in my react router config? Any pointers would be greatly appreciated.
回答1:
You may have a separate endpoint to check requested url, which returns page type like 'Product' or 'ProductList' and based on this result you can load more data
For example, let's say you have http://www.example.com/api/urlcheck
in your Router:
<Route exact path="/" component={ Home } />
<Route path="/:customPath" component={ Wrapper } />
in Wrapper
constructor(props) {
super(props)
this.state={
componentName: null
}
}
componentDidMount() {
let pathname = this.props.location.pathname.substr(1)
// alternatively you can get pathname from this.props.location.match.params.customPath
fetch(/* send request to http://www.example.com/api/urlcheck with pathname */)
.then((response)=>{ this.setState({componentName: response.componentName }) })
}
render (){
const { componentName } = this.state
if(componentName === 'Product') return <Product />
else if(componentName === 'ProductList') return <ProductList />
}
in Product or ProductList components in a similar way you can request for specific set of data by id or any other key.
Keep in mind though, if SEO is a big piece, you most likely want to have server side rendering, which is not happening in the example above. componentDidMount renders only in browser and you'll have to replace that with componentWillMount (the only function in react lifecycle that runs on SSR).
SSR is a bit of a pain, especially with requests that are based on responses from other requests. Redux-saga makes life so much easier with this kind of stuff, so I'd recommend to go saga way in your case as well.
You can take a look at react-saga-universal to quickly get up and running with saga and SSR.
来源:https://stackoverflow.com/questions/45266423/dynamic-paths-in-react-router