反应将父级传递给孩子的道具导致无限循环 [英] React parent passing props to a child causes infinite loops
问题描述
我要实现的目标:
我希望用户能够在画布上渲染的图片上放置红点.就是这样.
I want the user to be able to place red dots on a picture rendered in a canvas. That's it.
发生了什么事?
每次我添加所说的点(CanvasComponent
)时,它都在那里,然后在第二秒后消失.我认为这是因为画布一遍又一遍地重新渲染.我在componentWillReceiveProps
中添加了console.log
,它在一分钟内达到了k的最大值,并且崩溃了我的浏览器.
Every time I add said dots (CanvasComponent
), it is there, and then disappears a second later. I figured that's because the canvas is re-rendering over and over. I added a console.log
to componentWillReceiveProps
and it consoled up to a couple of k in a minute, and crashed my browser.
我看不到循环的来源,也许有人在这里有更多的技能或运气.
I cannot see where the loop is coming from, maybe someone here has more skills or luck.
这是我的代码:
DisplayPictureComponent
setDimensions = (width, height) => {
console.log('dimensions')
this.setState({width: width, height: height})
};
render() {
const {width, height} = this.state;
return (
<div>
<CanvasComponent width={width} height={height} image={this.props.image}/>
<ImageComponent
setDimensions={this.setDimensions}
image={this.props.image}/>
</div>
);
}
ImageComponent
componentWillReceiveProps(nextProps) {
console.log('imageProps')
const reader = new FileReader();
reader.onload = async e => {
await this.setState({image: e.target.result});
const image = document.getElementById('image');
const {naturalHeight, naturalWidth} = image;
nextProps.setDimensions(naturalWidth, naturalHeight);
};
reader.readAsDataURL(nextProps.image);
}
render() {
return (
<div>
<img style={{display: 'none'}} id={'image'} src={this.state.image} alt={''}/>
</div>
);
}
CanvasComponent
CanvasComponent
componentWillReceiveProps(nextProps) {
console.log('canvasProps');
// console.log('props');
this.ctx = document.getElementById('canvas').getContext('2d');
const img = new Image();
img.onload = () => {
this.ctx.drawImage(img, 0, 0, nextProps.width, nextProps.height);
};
img.src = URL.createObjectURL(nextProps.image)
}
handleClick = (e) => {
const canvas = document.getElementById('canvas');
this.Draw(e.pageX - canvas.offsetLeft, e.pageY - canvas.offsetTop);
};
Draw = (x, y) => {
console.log('drawing');
};
render() {
return (
<div>
<canvas onClick={this.handleClick} width={this.props.width} height={this.props.height} id={'canvas'}/>
</div>
);
}
推荐答案
对componentWillReceiveProps
的调用会更改道具,从而进行自我调用.
解决此问题的办法是比较当前的宽度和高度是否与下一个不同.
the call to the componentWillReceiveProps
changes the props, thereby calling itself.
A hack around this would be to compare if the current width and height isn't the same as the next.
componentWillReceiveProps(nextProps) {
console.log('imageProps')
const reader = new FileReader();
reader.onload = async e => {
await this.setState({image: e.target.result});
const image = document.getElementById('image');
const {naturalHeight, naturalWidth} = image;
if ((nextProps.width !== this.props.width) ||(nextProps.height !== this.props.height) ) {
nextProps.setDimensions(naturalWidth, naturalHeight);
}
};
reader.readAsDataURL(nextProps.image);
}
componentWillReceiveProps
已被弃用,您可以使用替代方法
componentWillReceiveProps
has been deprecated you can use the alternative
static getDerivedStateFromProps(nextProps, prevState) {
// Called after a component is instantiated or before it receives new props.
// Return an object to update state in response to prop changes.
// Return null to indicate no change to state.
}
您可以参考 RFC 了解有关为何进行此更改的更多信息.
You can refer to this RFC to understand more about why this change was made.
这篇关于反应将父级传递给孩子的道具导致无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!