我有一个 React 组件,其中包含许多子组件。我想不是立即渲染子组件,而是在一些延迟之后(每个子组件统一或不同)。
我想知道 - 有没有办法做到这一点?
我有一个 React 组件,其中包含许多子组件。我想不是立即渲染子组件,而是在一些延迟之后(每个子组件统一或不同)。
我想知道 - 有没有办法做到这一点?
我认为最直观的方法是给孩子一个 "wait" prop
,它在从父级传递下来的持续时间内隐藏组件。通过将默认状态设置为隐藏,React 仍然会立即渲染组件,但在状态改变之前它是不可见的。然后,您可以设置componentWillMount
在通过 props 传递的持续时间之后调用一个函数来显示它。
var Child = React.createClass({
getInitialState : function () {
return({hidden : "hidden"});
},
componentWillMount : function () {
var that = this;
setTimeout(function() {
that.show();
}, that.props.wait);
},
show : function () {
this.setState({hidden : ""});
},
render : function () {
return (
<div className={this.state.hidden}>
<p>Child</p>
</div>
)
}
});
然后,在 Parent 组件中,您需要做的就是传递您希望 Child 在显示之前等待的持续时间。
var Parent = React.createClass({
render : function () {
return (
<div className="parent">
<p>Parent</p>
<div className="child-list">
<Child wait={1000} />
<Child wait={3000} />
<Child wait={5000} />
</div>
</div>
)
}
});
延迟组件的另一种方法:
Delayed.jsx
:
import React from 'react';
import PropTypes from 'prop-types';
class Delayed extends React.Component {
constructor(props) {
super(props);
this.state = {hidden : true};
}
componentDidMount() {
setTimeout(() => {
this.setState({hidden: false});
}, this.props.waitBeforeShow);
}
render() {
return this.state.hidden ? '' : this.props.children;
}
}
Delayed.propTypes = {
waitBeforeShow: PropTypes.number.isRequired
};
export default Delayed;
用法:
import Delayed from '../Time/Delayed';
import React from 'react';
const myComp = props => (
<Delayed waitBeforeShow={500}>
<div>Some child</div>
</Delayed>
)
我使用Hooks 和 TypeScript创建了延迟组件
import React, { useState, useEffect } from 'react';
type Props = {
children: React.ReactNode;
waitBeforeShow?: number;
};
const Delayed = ({ children, waitBeforeShow = 500 }: Props) => {
const [isShown, setIsShown] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsShown(true);
}, waitBeforeShow);
}, [waitBeforeShow]);
return isShown ? children : null;
};
export default Delayed;
只需将另一个组件包装到 Delayed
export const LoadingScreen = () => {
return (
<Delayed>
<div />
</Delayed>
);
};
在您的父亲组件中<Father />
,您可以创建一个初始状态,您可以在其中跟踪每个孩子(例如 using 和 id),分配一个布尔值,这意味着是否渲染:
getInitialState() {
let state = {};
React.Children.forEach(this.props.children, (child, index) => {
state[index] = false;
});
return state;
}
然后,当组件被挂载时,你启动你的计时器来改变状态:
componentDidMount() {
this.timeouts = React.Children.forEach(this.props.children, (child, index) => {
return setTimeout(() => {
this.setState({ index: true; });
}, child.props.delay);
});
}
当你渲染你的孩子时,你通过重新创建他们来完成它,将匹配的孩子的状态分配为props,说明是否必须渲染组件。
let children = React.Children.map(this.props.children, (child, index) => {
return React.cloneElement(child, {doRender: this.state[index]});
});
所以在你的<Child />
组件中
render() {
if (!this.props.render) return null;
// Render method here
}
当超时被触发时,状态会发生变化并重新渲染父组件。子props被更新,如果doRender
是true
,它们将呈现自己。
取决于您的用例。
如果你想做一些儿童融入的动画,使用 react 动画插件:https : //facebook.github.io/react/docs/animation.html 否则,让孩子的渲染依赖于 props 并添加一些延迟后的props。
我不会延迟组件,因为它可能会在测试过程中困扰你。理想情况下,组件应该是纯的。