动态React-Router 1.0.0-rc3

时间:2015-10-30 20:33:48

标签: reactjs react-router

  

无论我从反应路由器的人那里读到什么,我   我喜欢我的应用程序的路由器有动态数据,我已经成功   在这样做时,有一点需要注意:我不能递归循环为孩子   路由。

这是一个有效的动态反应路由器:

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'));

正如我所说的,这只适用于第一级,当我尝试递归遍历任何childNodes时,我收到错误:

  

TypeError:无法读取未定义的属性'fetchMenuSystem'

我尝试将调用绑定到fetch函数并绑定映射,但没有一个工作。

我非常感谢你们的帮助。

1 个答案:

答案 0 :(得分:1)

OK, I solved this. The problem lied with the routes state & the 'this' keyword.

Here are the changes:

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';