Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在react路由器中调用getComponent时如何显示加载UI?_Javascript_Reactjs_React Router_React Redux - Fatal编程技术网

Javascript 在react路由器中调用getComponent时如何显示加载UI?

Javascript 在react路由器中调用getComponent时如何显示加载UI?,javascript,reactjs,react-router,react-redux,Javascript,Reactjs,React Router,React Redux,我真的是个新手,我不知道如何在路由加载getComponent时呈现“加载…”屏幕。getComponent调用可以正常工作并显示组件,但是UI上没有任何迹象表明请求和响应之间发生了任何事情。这就是我想弄明白的 import Main from './pages/Main.jsx'; import Test from './pages/Test.jsx'; import Home from './pages/Home.jsx'; var Routes = { path: "/", c

我真的是个新手,我不知道如何在路由加载getComponent时呈现“加载…”屏幕。getComponent调用可以正常工作并显示组件,但是UI上没有任何迹象表明请求和响应之间发生了任何事情。这就是我想弄明白的

import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';


var Routes = {
  path: "/",
  component: Main,
  indexRoute: {
    component: Home
  },
  childRoutes: [
    {
      path: "test",
      component: Test
    },
    {
      path: "about",
      getComponent: function(path, cb) {
        require.ensure([], (require) => {
          cb(null, require("./pages/about/About.jsx"));
        });
      }
    }
  ]
};

export default Routes;
在尝试使用OneNet或getComponent函数强制“加载”组件显示失败后,我想我应该尝试使用Redux将加载状态设置为true/false,并让我的主视图组件显示加载屏幕:

import React from 'react';
import {connect} from 'react-redux';

import NavBar from '../components/Navigation/NavBar.jsx';
import Footer from '../components/Footer.jsx';
import Loading from './Loading.jsx';
import navItems from '../config/navItems.jsx';
import setLoading from '../actions/Loading.jsx';

var Main = React.createClass({
  renderPage: function() {
    if (this.props.loading) {
      return (
        <Loading/>
      );
    } else {
      return this.props.children;
    }
  },
  render: function() {
    return (
      <div>
        <header id="main-header">
          <NavBar navigation={navItems}/>
        </header>
        <section id="main-section">
          {this.renderPage()}
        </section>
        <Footer id="main-footer" />
      </div>
    );
  }
});

function mapStateToProps(state) {
  return {
    loading: state.loading
  }
}

export default connect(mapStateToProps)(Main);
AsyncRoute.jsx页面如下所示:

import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';
import AsyncRoute from './pages/AsyncRoute.jsx';


var Routes = {
  path: "/",
  component: Main,
  indexRoute: {
    component: Home
  },
  childRoutes: [
    {
      path: "test",
      component: Test
    },
    {
      path: "about",
      component: AsyncRoute("about")
    }
  ]
};

export default Routes;
import React from 'react';

function getRoute(route, component) {
  switch(route) {
    // add each route in here
    case "about":
      require.ensure([], (require) => {
        component.Page = require("./about/About.jsx");
        component.setState({loading: false});
      });
    break;
  }
}

var AsyncRoute = function(route) {
  return React.createClass({
    getInitialState: function() {
      return {
        loading: true
      }
    },
    componentWillMount: function() {
      getRoute(route, this);
    },
    render: function() {
      if (this.state.loading) {
        return (
          <div>Loading...</div>
        );
      } else {
        return (
          <this.Page/>
        );
      }
    }
  });
};

export default AsyncRoute;
export default connect(state => state)(Main);
var Page = function(route) {
  return React.createClass({
    getInitialState: function() {
      // kick off async loading here
    },
    render: function() {
      if (!this.props.myRequiredData) {
        return (
          <Loading />
        );
      } else {
        return (
          // display this.props.myRequiredData
        );
      }
    }
  });
};
从“React”导入React;
函数getRoute(路由、组件){
道岔(进路){
//在这里添加每条路线
案例“关于”:
要求。确保([],(要求)=>{
component.Page=require(“./about/about.jsx”);
setState({loading:false});
});
打破
}
}
var AsyncRoute=函数(路由){
返回React.createClass({
getInitialState:函数(){
返回{
加载:正确
}
},
componentWillMount:function(){
getRoute(route,this);
},
render:function(){
if(this.state.loading){
返回(
加载。。。
);
}否则{
返回(
);
}
}
});
};
导出默认异步路由;

如果有人有更好的想法,请告诉我。

好的,让我们看看我是否可以在这里解释一下:

我不知道如何从路由器中访问存储/调度程序

没有必要马上这么做。您可以指定所有路由,列出应对每个路由进行应答的组件(就像上面所做的那样),然后将每个组件连接到redux存储。对于连接,可以用更简单的方式编写
MapStateTrops
函数,如下所示:

import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';
import AsyncRoute from './pages/AsyncRoute.jsx';


var Routes = {
  path: "/",
  component: Main,
  indexRoute: {
    component: Home
  },
  childRoutes: [
    {
      path: "test",
      component: Test
    },
    {
      path: "about",
      component: AsyncRoute("about")
    }
  ]
};

export default Routes;
import React from 'react';

function getRoute(route, component) {
  switch(route) {
    // add each route in here
    case "about":
      require.ensure([], (require) => {
        component.Page = require("./about/About.jsx");
        component.setState({loading: false});
      });
    break;
  }
}

var AsyncRoute = function(route) {
  return React.createClass({
    getInitialState: function() {
      return {
        loading: true
      }
    },
    componentWillMount: function() {
      getRoute(route, this);
    },
    render: function() {
      if (this.state.loading) {
        return (
          <div>Loading...</div>
        );
      } else {
        return (
          <this.Page/>
        );
      }
    }
  });
};

export default AsyncRoute;
export default connect(state => state)(Main);
var Page = function(route) {
  return React.createClass({
    getInitialState: function() {
      // kick off async loading here
    },
    render: function() {
      if (!this.props.myRequiredData) {
        return (
          <Loading />
        );
      } else {
        return (
          // display this.props.myRequiredData
        );
      }
    }
  });
};
关于
加载
状态:我认为加载缓慢组件并在加载时显示等待指示器是错误的一步。我希望有一个快速加载组件,从后端异步加载其所有数据,当数据还不可用时,该组件呈现一个等待指示器。一旦数据可用,就可以显示它。这基本上就是您在第二次编辑中绘制的

如果您可以将其从实际数据中删除,即无数据显示->显示加载屏幕/数据显示->显示真实屏幕,则会更好。这样,您可以避免在加载标志不同步时出现问题。(更严格地说:避免冗余。)

因此,我宁愿为加载屏幕创建一个独立的组件,并在每个组件感觉需要时显示它,而不是使包装器通用。(这些需求是不同的,因此似乎很难以通用的方式处理这一问题。)类似这样:

import Main from './pages/Main.jsx';
import Test from './pages/Test.jsx';
import Home from './pages/Home.jsx';
import AsyncRoute from './pages/AsyncRoute.jsx';


var Routes = {
  path: "/",
  component: Main,
  indexRoute: {
    component: Home
  },
  childRoutes: [
    {
      path: "test",
      component: Test
    },
    {
      path: "about",
      component: AsyncRoute("about")
    }
  ]
};

export default Routes;
import React from 'react';

function getRoute(route, component) {
  switch(route) {
    // add each route in here
    case "about":
      require.ensure([], (require) => {
        component.Page = require("./about/About.jsx");
        component.setState({loading: false});
      });
    break;
  }
}

var AsyncRoute = function(route) {
  return React.createClass({
    getInitialState: function() {
      return {
        loading: true
      }
    },
    componentWillMount: function() {
      getRoute(route, this);
    },
    render: function() {
      if (this.state.loading) {
        return (
          <div>Loading...</div>
        );
      } else {
        return (
          <this.Page/>
        );
      }
    }
  });
};

export default AsyncRoute;
export default connect(state => state)(Main);
var Page = function(route) {
  return React.createClass({
    getInitialState: function() {
      // kick off async loading here
    },
    render: function() {
      if (!this.props.myRequiredData) {
        return (
          <Loading />
        );
      } else {
        return (
          // display this.props.myRequiredData
        );
      }
    }
  });
};
var页面=功能(路由){
返回React.createClass({
getInitialState:函数(){
//在这里开始异步加载
},
render:function(){
如果(!this.props.myRequiredData){
返回(
);
}否则{
返回(
//显示此.props.myRequiredData
);
}
}
});
};

我想我已经解决了这个问题。这可能是正确的方式,也可能不是正确的方式,但似乎有效。我也不知道为什么我之前没有想到这一点

首先,将我的createStore代码移动到它自己的文件(store.jsx)中,这样我就可以将它导入到主入口点以及Routes.jsx文件中:

import {createStore} from 'redux';
import rootReducer from '../reducers/Root.jsx';

var store = createStore(rootReducer);

export default store;
jsx看起来像这样(这是一个难看的混乱,但我只是想得到一些基本的东西,然后我会清理它):

我制作了一个基本组件,根据Redux存储的“加载”值显示加载/加载:

这似乎奏效了。只要单击
转到/about路由,就会发送一个操作,将主存储中的“加载”状态设置为true。这会导致
组件自我更新(我设想它最终会在窗口的角落呈现一个微调器或类似的东西)。这个奇怪的
需要。确保运行([])
函数以使webpack执行其奇特的代码拆分,一旦加载组件,则会调度另一个操作以将加载状态设置为false,并呈现组件


我还是一个新的反应者,虽然这似乎有效,但我不确定这是否是正确的方法。如果有人有更好的办法,请插话

遵循与@David M相同的方法,我实现了一个加载缩减器和一个包装调度的函数

除店铺创建和管理外,基本情况如下:

负载减速器:

import withLoader from 'withLoader'
import store from 'store'

const route = {
    path: 'mypath',
    getComponent: withLoader((nextState, cb) => {
        require.ensure([], require => {
            cb(null, require('something').default)
        }, 'NamedBundle')
    }, store)
}
export default route
//------------------------------------
//常数
// ------------------------------------
导出常量加载='加载'
// ------------------------------------
//行动
// ------------------------------------
const loadQueue=[]
导出常量加载=加载=>{
如果(装载){
loadQueue.push(true)
}否则{
loadQueue.pop()
}
返回{
类型:装载,
有效负载:loadQueue.length>0
}
}
导出常量操作={
加载
}
// ------------------------------------
//动作处理程序
// ------------------------------------
常量操作\u处理程序={
[加载]:(状态,操作)=>(action.payload)
}
// ------------------------------------
//减速器
// ------------------------------------
常量initialState=false
导出默认函数缩减器(状态=初始状态,操作){
const handler=ACTION\u HANDLERS[ACTION.type]
返回处理程序?处理程序(状态,操作):状态
}
请注意,
loadingQueue
如何使加载消息保持活动状态