动态 React-Router 1.0.0-rc3
Dynamic React-Router 1.0.0-rc3
Regardless of what I have read from the folks at react-router, I
prefer my app's router have dynamic data, and I have been successful
in doing it, with one caveat: I cannot loop recursively for child
routes.
这是一个工作的动态反应路由器:
export default class Index extends React.Component {
constructor() {
super();
this.state = {
navItems: [] };
}
componentWillMount() {
NavMenuAPI.getAll()
.then((response) => {
const data = response.data;
this.setState({ navItems: data });
});
}
fetchMenuSystem(data) {
const routes = [];
data.map(function(route) {
let routePaths = [];
let component = {};
if (route.linkTo === '/') {
const pageApp = route.title.replace(/ /g, '-').toLocaleLowerCase();
component = require('./components/pages/' + pageApp);
} else {
const pageApp = route.title.replace(/ /g, '-').toLocaleLowerCase();
component = require('./components/pages/' + pageApp);
}
if (route.paths === undefined) {
routePaths.push(route.linkTo);
} else {
routePaths = JSON.parse(JSON.stringify(route.paths));
}
routePaths.map(function(path) {
const props = { key: path, path, component };
// Static `onEnter` is defined on
// component, we should pass it to route props
// if (component.onEnter) props.onEnter = component.onEnter;
routes.push(<Route { ...props } />);
});
//////////////////////////////////////////////
// PROBLEM !!!!!!!!!!
// if (route.childNodes !== undefined) {
// this.fetchMenuSystem(route.childNodes);
// }
});
return routes;
}
fetchRoutes() {
const data = this.state.navItems;
const result = this.fetchMenuSystem(data);
return (
<Route component={ require('./components/APP') }>
{ result }
<Route path="*" component={ require('./components/pages/not-found') }/>
</Route>
);
}
render() {
if (this.state.navItems.length === 0) return <div>Loading ...</div>;
const routerProps = {
routes: this.fetchRoutes(),
history: createHistory({
queryKey: false
}),
createElement: (component, props) => {
return React.createElement(component, { ...props });
}
};
return (
<Router { ...routerProps } />
);
}
}
ReactDOM.render(<Index />, document.getElementById('reactRoot'));
正如我所说,这只适用于第一级,当我尝试递归循环任何子节点时,我收到错误:
TypeError: Cannot read property 'fetchMenuSystem' of undefined
我尝试将调用绑定到获取函数并绑定映射,none 有效。
非常感谢对此的帮助。
好的,我解决了这个问题。问题在于路由状态和 'this' 关键字。
更改如下:
export default class Index extends React.Component {
constructor() {
super();
this.state = {
navItems: [],
routes: []
};
}
................
fetchMenuSystem(data) {
const currRoutesState = this.state.routes;
const self = this;
data.map(function(route) {
................
routePaths.map(function(path) {
................
currRoutesState.push(<Route { ...props } />);
});
if (route.childNodes !== undefined) {
self.fetchMenuSystem(route.childNodes);
}
});
return currRoutesState;
}
................
}
Final thoughts if you plan on using this:
[Re: npm install --save history]
I had to opt for 100% client side routing,
(not isomorphic/universal) so in my imports ....
import createHistory from 'history/lib/createHashHistory';
// import createBrowserHistory from 'history/lib/createBrowserHistory';
Regardless of what I have read from the folks at react-router, I prefer my app's router have dynamic data, and I have been successful in doing it, with one caveat: I cannot loop recursively for child routes.
这是一个工作的动态反应路由器:
export default class Index extends React.Component {
constructor() {
super();
this.state = {
navItems: [] };
}
componentWillMount() {
NavMenuAPI.getAll()
.then((response) => {
const data = response.data;
this.setState({ navItems: data });
});
}
fetchMenuSystem(data) {
const routes = [];
data.map(function(route) {
let routePaths = [];
let component = {};
if (route.linkTo === '/') {
const pageApp = route.title.replace(/ /g, '-').toLocaleLowerCase();
component = require('./components/pages/' + pageApp);
} else {
const pageApp = route.title.replace(/ /g, '-').toLocaleLowerCase();
component = require('./components/pages/' + pageApp);
}
if (route.paths === undefined) {
routePaths.push(route.linkTo);
} else {
routePaths = JSON.parse(JSON.stringify(route.paths));
}
routePaths.map(function(path) {
const props = { key: path, path, component };
// Static `onEnter` is defined on
// component, we should pass it to route props
// if (component.onEnter) props.onEnter = component.onEnter;
routes.push(<Route { ...props } />);
});
//////////////////////////////////////////////
// PROBLEM !!!!!!!!!!
// if (route.childNodes !== undefined) {
// this.fetchMenuSystem(route.childNodes);
// }
});
return routes;
}
fetchRoutes() {
const data = this.state.navItems;
const result = this.fetchMenuSystem(data);
return (
<Route component={ require('./components/APP') }>
{ result }
<Route path="*" component={ require('./components/pages/not-found') }/>
</Route>
);
}
render() {
if (this.state.navItems.length === 0) return <div>Loading ...</div>;
const routerProps = {
routes: this.fetchRoutes(),
history: createHistory({
queryKey: false
}),
createElement: (component, props) => {
return React.createElement(component, { ...props });
}
};
return (
<Router { ...routerProps } />
);
}
}
ReactDOM.render(<Index />, document.getElementById('reactRoot'));
正如我所说,这只适用于第一级,当我尝试递归循环任何子节点时,我收到错误:
TypeError: Cannot read property 'fetchMenuSystem' of undefined
我尝试将调用绑定到获取函数并绑定映射,none 有效。
非常感谢对此的帮助。
好的,我解决了这个问题。问题在于路由状态和 'this' 关键字。
更改如下:
export default class Index extends React.Component {
constructor() {
super();
this.state = {
navItems: [],
routes: []
};
}
................
fetchMenuSystem(data) {
const currRoutesState = this.state.routes;
const self = this;
data.map(function(route) {
................
routePaths.map(function(path) {
................
currRoutesState.push(<Route { ...props } />);
});
if (route.childNodes !== undefined) {
self.fetchMenuSystem(route.childNodes);
}
});
return currRoutesState;
}
................
}
Final thoughts if you plan on using this:
[Re: npm install --save history]
I had to opt for 100% client side routing, (not isomorphic/universal) so in my imports ....
import createHistory from 'history/lib/createHashHistory';
// import createBrowserHistory from 'history/lib/createBrowserHistory';