【问题标题】:React parent passing props to a child causes infinite loops反应父母将道具传递给孩子会导致无限循环
【发布时间】:2019-05-13 11:59:11
【问题描述】:

我想要达到的目标:

我希望用户能够在画布中呈现的图片上放置红点。就是这样。

发生了什么事?

每次我添加所说的点 (CanvasComponent),它就在那里,然后在一秒钟后消失。我认为这是因为画布一遍又一遍地重新渲染。我在componentWillReceiveProps 中添加了一个console.log,它在一分钟内控制了几个k,然后我的浏览器崩溃了。

我看不到循环来自哪里,也许这里的某人有更多的技能或运气。

这是我的代码:

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>
    );
}

画布组件

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>
    );
}

【问题讨论】:

  • 是什么触发了ImageComponent上的setDimensions
  • 加载图片reader.onload = async e =&gt; {...
  • 在Image组件nextProps.setDimension()中,你想要达到的效果
  • 我想获取用户上传的图片的尺寸,以创建具有正确宽度和高度的画布
  • 我还没有尝试过代码,但我认为对componentWillReceiveProps 的调用会改变道具,从而调用自身。解决这个问题的方法是比较当前的宽度和高度是否与下一个不同。

标签: javascript reactjs loops recursion


【解决方案1】:

componentWillReceiveProps 的调用会更改道具,从而调用自身。 解决这个问题的方法是比较当前的宽度和高度是否与下一个不同。

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 已被弃用,您可以使用替代方法

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 以详细了解为何进行此更改。

【讨论】:

  • 您当前的代码可能需要一些重构才能使用getDerivedStateFromProps
猜你喜欢
  • 2018-03-29
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 2020-04-06
相关资源
最近更新 更多