ReactJS:如何在所有平台上创建共享单例组件?

mar*_*uir 7 javascript ajax reactjs

我正在考虑创建一个名为LoadingMask的React组件,我可以在其中显示或不显示(取决于状态)来自任何组件的加载掩码.这个想法是在ajax调用之前显示它,并在我收到数据后隐藏它.

我不想同时显示两个掩码,所以如果一个组件正在发出请求,另一个组件创建另一个请求,我想在我的"MaskCounter"中添加1,并在Request完成时减去一个.如果计数器为0,我需要隐藏LoadingMask.

我命令这样做,我想我需要创建一个"Singleton"组件,我可以通过整个平台共享,所以只存在一个LoadingMask.我也不认为发送事件隐藏/显示所有组件的掩码是很好的.

有任何想法吗?

soy*_*wod 3

要在组件之间共享数据,您可以:

class Application extends React.Component {
  constructor() {
    super();
    
    this.state = {
      nbTasks: 0
    };
    
    this.addTask = this.addTask.bind(this);
    this.removeTask = this.removeTask.bind(this);
    this.isLoading = this.isLoading.bind(this);
  }
  
  addTask() {
    this.setState(prevState => ({
      nbTasks: prevState.nbTasks + 1
    }));
  }
  
  removeTask() {
    this.setState(prevState => ({
      nbTasks: prevState.nbTasks - 1
    }));
  }
  
  isLoading() {
    return this.state.nbTasks > 0;
  }
  
  getChildContext() {
    return {
      addTask: this.addTask,
      removeTask: this.removeTask,
      isLoading: this.isLoading
    };
  }
  
  render() {
    return (
      <div>
        <ComponentX />
        <ComponentY />
        <LoadingMask />
      </div>
    );
  }
}

Application.childContextTypes = {
  addTask: PropTypes.func,
  removeTask: PropTypes.func,
  isLoading: PropTypes.func
};

const LoadingMask = (props, context) => (
  context.isLoading()
    ? <div>LOADING ...</div>
    : null
);

LoadingMask.contextTypes = {
  isLoading: PropTypes.func
};

class ComponentX extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      message: 'Processing ...'
    };
  }
  
  componentDidMount() {
    this.context.addTask();
    
    setTimeout(() => {
      this.setState({
        message: 'ComponentX ready !'
      });
      
      this.context.removeTask();
    }, 3500);
  }
  
  render() {
    return (
      <div>
        <button disabled>{this.state.message}</button>
      </div>
    );
  }
}

ComponentX.contextTypes = {
  addTask: PropTypes.func,
  removeTask: PropTypes.func
};

class ComponentY extends React.Component {
  constructor(props, context) {
    super(props, context);
    
    this.state = {
      message: 'Processing ...'
    };
  }
  
  componentDidMount() {
    this.context.addTask();
    
    setTimeout(() => {
      this.setState({
        message: 'ComponentY ready !'
      });
      
      this.context.removeTask();
    }, 6000);
  }
  
  render() {
    return (
      <div>
        <button disabled>{this.state.message}</button>
      </div>
    );
  }
}

ComponentY.contextTypes = {
  addTask: PropTypes.func,
  removeTask: PropTypes.func
};

ReactDOM.render(
  <Application />,
  document.getElementById('app')
);
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/prop-types/prop-types.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>

<div id="app"></app>
Run Code Online (Sandbox Code Playgroud)

  • “悬念”与全局状态管理无关。它与[延迟加载](https://reactjs.org/docs/code-splitting.html#suspense)有关,并且它不再处于测试阶段(自[v16.6.0](https://github.com/facebook /react/blob/master/CHANGELOG.md#1660-october-23-2018)) (2认同)