我正在考虑创建一个名为LoadingMask的React组件,我可以在其中显示或不显示(取决于状态)来自任何组件的加载掩码。这个想法是在ajax调用之前显示它,并在我收到数据后隐藏它。
我不想同时显示两个面具,所以如果一个组件正在发出请求,另一个组件创建另一个请求,我想向我的" MaskCounter"添加1。 ,并在请求完成时减去一个。如果计数器为0,我需要隐藏LoadingMask。
我要这样做,我想我需要创建一个" Singleton"我可以通过整个平台共享组件,因此只存在一个LoadingMask。我也不认为发送事件来隐藏/显示所有组件的掩码是很好的。
有什么想法吗?
答案 0 :(得分: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')
);
&#13;
<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>
&#13;