Reactjs 如何在componentDidMount后运行setInterval,并在道具更新后重新运行它?
这是我的代码笔代码Reactjs 如何在componentDidMount后运行setInterval,并在道具更新后重新运行它?,reactjs,Reactjs,这是我的代码笔代码 let jsonData = { value: [1,2,3,4,5,6,7,8,9,10] } class Father extends React.Component { constructor(props) { super(props); this.state = { data: jsonData,//data from websocket } } render() { const arr = this.st
let jsonData = {
value: [1,2,3,4,5,6,7,8,9,10]
}
class Father extends React.Component {
constructor(props) {
super(props);
this.state = {
data: jsonData,//data from websocket
}
}
render() {
const arr = this.state.data.value;
return (
<Child arr={arr} />
);
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
style: null,
arr: this.props.arr
};
}
getNodePositionBottom(ref) {
const nodeY = ReactDOM.findDOMNode(ref).getBoundingClientRect().bottom;
return nodeY;
}
getNodePositionTop(ref) {
const nodeY = ReactDOM.findDOMNode(ref).getBoundingClientRect().top;
return nodeY;
}
componentDidMount() {
const divBottom = this.getNodePositionBottom(this.div);
const divTop = this.getNodePositionTop(this.div);
const height = divBottom - divTop;
const ulBottom = this.getNodePositionBottom(this.ul);
const ulTop = this.getNodePositionTop(this.ul);
const heightUL = ulBottom - ulTop;
if (ulBottom > divBottom) {
this.scrollingTop = setInterval(
function(){
this.offsetY = this.offsetY || 0;
if (ulBottom > divTop && this.offsetY + heightUL!== 0) {
this.offsetY -= 1;
this.setState({
style: {top: + this.offsetY + "px"}
});
} else {
this.setState({
style: {top: height + "px"}
});
this.offsetY = height;
}
}.bind(this),
20
);
}
}
render() {
const arr = this.state.arr;
let arrList = arr.map((name, i) => <li key={i} className="list">{name}</li>);
return (
<div ref={(div) => {this.div = div}} className="father">
<ul ref={(ul) => {this.ul = ul}} className="child" style={this.state.style}>
{arrList}
</ul>
</div>
);
}
}
ReactDOM.render(<Father />, document.getElementById("app"));
让jsonData={
值:[1,2,3,4,5,6,7,8,9,10]
}
类父类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
数据:jsonData,//来自websocket的数据
}
}
render(){
const arr=this.state.data.value;
返回(
);
}
}
子类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
样式:空,
这个。道具。啊
};
}
getNodePositionBottom(参考){
const nodeY=ReactDOM.findDOMNode(ref.getBoundingClientRect().bottom;
返回诺迪;
}
getNodePositionTop(参考){
const nodeY=ReactDOM.findDOMNode(ref.getBoundingClientRect().top;
返回诺迪;
}
componentDidMount(){
const divBottom=this.getNodePositionBottom(this.div);
const divTop=this.getNodePositionTop(this.div);
const height=divBottom-divTop;
const ulBottom=this.getNodePositionBottom(this.ul);
const ulTop=this.getNodePositionTop(this.ul);
常数heightUL=ulBottom-ulTop;
if(ulBottom>divBottom){
this.scrollingTop=setInterval(
函数(){
this.offsetY=this.offsetY | | 0;
如果(ulBottom>divTop&&this.offsetY+heightUL!==0){
此.offsetY-=1;
这是我的国家({
样式:{top:+this.offsetY+“px”}
});
}否则{
这是我的国家({
样式:{top:height+“px”}
});
this.offsetY=高度;
}
}.绑定(此),
20
);
}
}
render(){
const arr=this.state.arr;
设arrList=arr.map((name,i)=>{name} );
返回(
{this.div=div}}className=“父亲”>
{this.ul=ul}}className=“child”style={this.state.style}>
{arrList}
);
}
}
ReactDOM.render(,document.getElementById(“app”);
我试图构建一个列表,如果列表高度高于容器,则在渲染后自动滚动到上面。通过websocket数据更新列表成员,在每个websocket消息之后,更新列表成员,并再次比较高度以确定是否自动滚动
我对React是新手,所以我想到的就是设置一个“样式”状态,计算组件中的偏移量,然后重新设置状态,所以React将再次渲染
在我发现两个问题之前,它运行良好
第一个问题是我想通过websocket数据更新这个列表,我认为“道具改变了,它会重新呈现,因此状态也改变了”,但这会搞乱第二个问题,似乎我把这个自动滚动部分弄错了
正如您所知,组件通常通过每个状态渲染一次,但在这种情况下,我可能会将状态设置太多次,每20毫秒一次,我担心性能
每次从websocket服务器推送后,列表确实会变为新列表,但它会停止自动滚动
总而言之:
1“每隔20毫秒设置一次状态以执行自动滚动”是否错误
2为什么在通过道具更新后停止自动滚动?我应该使用componentDidUpdate吗?但这种生命周期方法会弄乱自动滚动,因为它会频繁运行
ComponentWillReceiveProps
,它具有nextrops(新的props本身)。你可以比较当前的道具和下一个道具,看看是否有任何变化,如果有,然后启动滚动ComponentWillReceiveProps(nextProps){
if (this.props.myName !== nextProps.myName) {
// do the code
}
}
我用ComponentWillReceiveProps解决了这个问题,除了生命周期方法之外,我还需要在setInterval中重置一些变量,这样它就可以计算出正确的偏移量。多亏了你们,现在我对生命周期有了更多的了解。