创建一个 React 高阶组件,用作 child 组件的 "loader"(动画)包装器
Creating a React higher order component, to serve as a "loader"(animation) wrapper for child components
我有很多组件,需要在 componentDidMount 方法中发送一些 ajax 函数。我想创建一个 HOC,其唯一目的是 "apply" 为组件添加一些动画,并在解决某个承诺后停止此动画。
当然,我可以为每个组件复制粘贴此代码,但我想创建一些抽象来处理它。
问题是,我不知道如何正确地传递函数,从 child 到 parent。例如,假设预期的 child 组件具有此 componentDidMount:
componentDidMount() {
ajax('/costumers')
.then(({ data }) => {
this.setState(() => ({ costumers: data.content }))
})
}
从技术上讲,我需要将此函数作为参数传递给 HOC,或者可能以某种方式 "hijack" child 的 componentDidMount(如果可能的话...)。 HOC 然后会在加载后应用动画,然后发送 ajax,只有当它被解决时,动画才会被消除,并且 child 组件被渲染。
如何实现?
任何想法将不胜感激
这是为这种情况编写 HOC 的方法,有关该主题的更多信息,请参阅 React docs。
const withLoader = (loader, Component) =>
class WithLoader extends React.Component {
state = { ready: false, data: null };
async componentDidMount() {
const data = await loader();
this.setState({ ready: true, data });
}
render() {
if (!this.state.ready) return <div>LOADING</div>; // or <ComponentWithAnimation />
return <Component data={this.state.data} />;
}
};
const Test = props => <div>DATA: {props.data}</div>;
const fakeLoader = () =>
new Promise(res => setTimeout(() => res("My data"), 1000));
const TestWithLoader = withLoader(fakeLoader, Test);
我有很多组件,需要在 componentDidMount 方法中发送一些 ajax 函数。我想创建一个 HOC,其唯一目的是 "apply" 为组件添加一些动画,并在解决某个承诺后停止此动画。
当然,我可以为每个组件复制粘贴此代码,但我想创建一些抽象来处理它。
问题是,我不知道如何正确地传递函数,从 child 到 parent。例如,假设预期的 child 组件具有此 componentDidMount:
componentDidMount() {
ajax('/costumers')
.then(({ data }) => {
this.setState(() => ({ costumers: data.content }))
})
}
从技术上讲,我需要将此函数作为参数传递给 HOC,或者可能以某种方式 "hijack" child 的 componentDidMount(如果可能的话...)。 HOC 然后会在加载后应用动画,然后发送 ajax,只有当它被解决时,动画才会被消除,并且 child 组件被渲染。
如何实现?
任何想法将不胜感激
这是为这种情况编写 HOC 的方法,有关该主题的更多信息,请参阅 React docs。
const withLoader = (loader, Component) =>
class WithLoader extends React.Component {
state = { ready: false, data: null };
async componentDidMount() {
const data = await loader();
this.setState({ ready: true, data });
}
render() {
if (!this.state.ready) return <div>LOADING</div>; // or <ComponentWithAnimation />
return <Component data={this.state.data} />;
}
};
const Test = props => <div>DATA: {props.data}</div>;
const fakeLoader = () =>
new Promise(res => setTimeout(() => res("My data"), 1000));
const TestWithLoader = withLoader(fakeLoader, Test);