Reactjs 对所有路线上的装载屏幕作出反应?

Reactjs 对所有路线上的装载屏幕作出反应?,reactjs,react-router,Reactjs,React Router,我知道如何获得带有状态和componentDidMount()的旋转屏幕,但如何在所有路由之间创建加载屏幕,而不必在每个组件中写入componentDidMount() 我的app.js文件 class App extends Component { constructor(props) { super(props); this.child = React.createRef(); } onWaypoint = () => { this.child.

我知道如何获得带有
状态
componentDidMount()
的旋转屏幕,但如何在所有路由之间创建加载屏幕,而不必在每个组件中写入
componentDidMount()

我的app.js文件

class App extends Component {

  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onWaypoint = () => {
    this.child.current.navChangeHandler();
  }

  render() {

    let routes = (
      <Switch>    
        <Route exact path="/projects" component={Projects} />
        <Route exact path="/about" component={About} />
        <Route exact path="/gallery" component={Gallery} />
        <Route exact path="/" component={Home} />
        <Redirect exact to="/" />
      </Switch>
    )

    return (
      <BrowserRouter>
        <div className="App" styleName="main-wrapper">
          <Layout>
              {routes}
              <Navigation ref={this.child} />
          </Layout>
        </div>
      </BrowserRouter>

    );
  }
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
this.child=React.createRef();
}
航路点=()=>{
this.child.current.navChangeHandler();
}
render(){
让路线=(
)
返回(
{routes}
);
}
}
我希望能够在这些路由之间看到一个微调器。

您可以在子组件上创建一个包装函数。然后,如果需要,您可以将HOC方法传递给子级并让子级调用该方法

例如:

家长:

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.setState({ isLoading: true });
      }
    };

    doneLoading = () => this.setState({ isLoading: false })

    render = () => (
      <WrappedComponent
        doneLoading={this.doneLoading}
        isLoading={this.state.isLoading}
        {...this.props}
      />
    );
  }
  return withRouter(Wrapper);
};
export default class Child extends PureComponent {

  componentDidMount = () => {
    fetch("someURL")
      .then(response => response.json())
      .then(json => this.setState({ list: json }), () => this.props.doneLoading());
  };

  render = () =>
    this.props.isLoading 
      ? <Spinner />
      : <DisplayList list={...this.state.list} />
}
缺点是每个子组件都需要导入
Spinner
,并检查
isLoading
是否为false

局限性 为了在嵌套较多的组件之间工作,您很可能需要集成Redux。此外,您还需要一个已装载的容器分派一个操作,以便在每次路由更改时更新/重置
isLoading
Redux状态。不管怎样,如果你想保持干燥,这都不是一个简单而优雅的解决方案


例子 工作示例(此示例仅通过超时设置/取消设置了HOC状态):

Wrapper.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Header from "./Header";
import Spinner from "./Spinner";

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidMount = () => this.setTimer();

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.clearTimer();
        this.setState({ isLoading: true }, () => this.setTimer());
      }
    };

    clearTimer = () => clearTimeout(this.timeout);

    timer = () => this.setState({ isLoading: false }, () => this.clearTimer());

    setTimer = () => (this.timeout = setTimeout(this.timer, 3000));

    render = () => (
      <Fragment>
        <Header />
        {this.state.isLoading
          ? <Spinner />
          : <WrappedComponent {...this.props} />
      </Fragment>
    );
  }
  return withRouter(Wrapper);
};
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Schedule from "../components/Schedule";
import Wrapper from "./components/Wrapper";

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Wrapper(Home)} />
      <Route path="/schedule" component={Wrapper(Schedule)} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);
import React,{Component,Fragment}来自“React”;
从“react router”导入{withRouter};
从“/Header”导入标题;
从“/Spinner”导入微调器;
导出默认WrappedComponent=>{
类包装器扩展组件{
状态={isLoading:true};
componentDidMount=()=>this.setTimer();
componentDidUpdate=prevProps=>{
if(this.props.location!==prevProps.location){
这个.clearTimer();
this.setState({isLoading:true},()=>this.setTimer());
}
};
clearTimer=()=>clearTimeout(this.timeout);
timer=()=>this.setState({isLoading:false},()=>this.clearTimer());
setTimer=()=>(this.timeout=setTimeout(this.timer,3000));
渲染=()=>(
{this.state.isLoading
? 
: 
);
}
用路由器(包装器)返回;
};
index.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Header from "./Header";
import Spinner from "./Spinner";

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidMount = () => this.setTimer();

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.clearTimer();
        this.setState({ isLoading: true }, () => this.setTimer());
      }
    };

    clearTimer = () => clearTimeout(this.timeout);

    timer = () => this.setState({ isLoading: false }, () => this.clearTimer());

    setTimer = () => (this.timeout = setTimeout(this.timer, 3000));

    render = () => (
      <Fragment>
        <Header />
        {this.state.isLoading
          ? <Spinner />
          : <WrappedComponent {...this.props} />
      </Fragment>
    );
  }
  return withRouter(Wrapper);
};
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Schedule from "../components/Schedule";
import Wrapper from "./components/Wrapper";

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Wrapper(Home)} />
      <Route path="/schedule" component={Wrapper(Schedule)} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);
从“React”导入React;
从“react dom”导入{render};
从“react router dom”导入{BrowserRouter,Switch,Route};
从“./组件/主目录”导入主目录;
从“./组件/计划”导入计划;
从“/components/Wrapper”导入包装器;
渲染(
,
document.getElementById(“根”)
);
您可以在子组件上创建包装函数。然后,如果需要,您可以将HOC方法传递给子组件,并让子组件调用该方法

例如:

家长:

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.setState({ isLoading: true });
      }
    };

    doneLoading = () => this.setState({ isLoading: false })

    render = () => (
      <WrappedComponent
        doneLoading={this.doneLoading}
        isLoading={this.state.isLoading}
        {...this.props}
      />
    );
  }
  return withRouter(Wrapper);
};
export default class Child extends PureComponent {

  componentDidMount = () => {
    fetch("someURL")
      .then(response => response.json())
      .then(json => this.setState({ list: json }), () => this.props.doneLoading());
  };

  render = () =>
    this.props.isLoading 
      ? <Spinner />
      : <DisplayList list={...this.state.list} />
}
缺点是每个子组件都需要导入
Spinner
,并检查
isLoading
是否为false

局限性 为了在嵌套较多的组件中工作,您很可能希望/需要集成Redux。此外,您需要一个已安装的容器在每次路由更改时发送一个操作来更新/重置
isLoading
Redux状态。无论哪种方式,如果您想保持干燥,这都不是一个简单而优雅的解决方案


例子 工作示例(此示例仅通过超时设置/取消设置了HOC状态):

Wrapper.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Header from "./Header";
import Spinner from "./Spinner";

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidMount = () => this.setTimer();

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.clearTimer();
        this.setState({ isLoading: true }, () => this.setTimer());
      }
    };

    clearTimer = () => clearTimeout(this.timeout);

    timer = () => this.setState({ isLoading: false }, () => this.clearTimer());

    setTimer = () => (this.timeout = setTimeout(this.timer, 3000));

    render = () => (
      <Fragment>
        <Header />
        {this.state.isLoading
          ? <Spinner />
          : <WrappedComponent {...this.props} />
      </Fragment>
    );
  }
  return withRouter(Wrapper);
};
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Schedule from "../components/Schedule";
import Wrapper from "./components/Wrapper";

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Wrapper(Home)} />
      <Route path="/schedule" component={Wrapper(Schedule)} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);
import React,{Component,Fragment}来自“React”;
从“react router”导入{withRouter};
从“/Header”导入标题;
从“/Spinner”导入微调器;
导出默认WrappedComponent=>{
类包装器扩展组件{
状态={isLoading:true};
componentDidMount=()=>this.setTimer();
componentDidUpdate=prevProps=>{
if(this.props.location!==prevProps.location){
这个.clearTimer();
this.setState({isLoading:true},()=>this.setTimer());
}
};
clearTimer=()=>clearTimeout(this.timeout);
timer=()=>this.setState({isLoading:false},()=>this.clearTimer());
setTimer=()=>(this.timeout=setTimeout(this.timer,3000));
渲染=()=>(
{this.state.isLoading
? 
: 
);
}
用路由器(包装器)返回;
};
index.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Header from "./Header";
import Spinner from "./Spinner";

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidMount = () => this.setTimer();

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.clearTimer();
        this.setState({ isLoading: true }, () => this.setTimer());
      }
    };

    clearTimer = () => clearTimeout(this.timeout);

    timer = () => this.setState({ isLoading: false }, () => this.clearTimer());

    setTimer = () => (this.timeout = setTimeout(this.timer, 3000));

    render = () => (
      <Fragment>
        <Header />
        {this.state.isLoading
          ? <Spinner />
          : <WrappedComponent {...this.props} />
      </Fragment>
    );
  }
  return withRouter(Wrapper);
};
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Schedule from "../components/Schedule";
import Wrapper from "./components/Wrapper";

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Wrapper(Home)} />
      <Route path="/schedule" component={Wrapper(Schedule)} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);
从“React”导入React;
从“react dom”导入{render};
从“react router dom”导入{BrowserRouter,Switch,Route};
从“./组件/主目录”导入主目录;
从“./组件/计划”导入计划;
从“/components/Wrapper”导入包装器;
渲染(
,
document.getElementById(“根”)
);
我相信它可以帮助您实现这一目标,也可以从中受益

我相信它可以帮助您实现这一目标,也可以从中受益

我的尝试:

返回
在这种情况下,无论是
loginpath
还是
adminPaths
都没有路径
/
,因此加载的默认路径是
/
。如果根路径很重要,您可以使用
路径,因此它将与任何内容都不匹配。我使用的是
AnimatedSwitch
from,因此在转换之间的状态是ns很重要。有了它,你可以说什么时候加载或不加载。

我的尝试:

返回
在这种情况下,无论是
loginpath
还是
adminpath
都没有路径
/
,因此加载的默认路径是
/
。如果根路径很重要,则可以使用
路径,这样它就可以