【问题标题】:Refactoring UNSAFE_componentWillReceiveProps重构 UNSAFE_componentWillReceiveProps
【发布时间】:2018-11-24 06:23:41
【问题描述】:

我有一个IFrameComponent 组件,灵感来自this post

基本上是这样的:

class IFrameComponent extends React.Component {
    shouldComponentUpdate() {
        return false;
    }

    componentWillReceiveProps(nextProps) {
        if(this.props.content !== nextProps.content) {
            const html = getHTMLFromContent();
            const fdoc = this.iFrame.contentDocument;
            fdoc.write(html);
        }
    }

    render() {
        return (<iframe sandbox="..." ref={f => this.iFrame = f} />);
    }
}

现在componentWillReceiveProps 被认为是不安全的,我正试图摆脱它。

The ways React advices to refactor componentWillReceiveProps 基本上要么使用static getDerivedStateFromProps 要么使用componentDidUpdate

可悲的是,componentDidUpdate 永远不会被调用,因为shouldComponentUpdate 返回 false(我认为这很好?)而且我无法在静态方法 getDerivedStateFromProps 中访问 this.iFrame 引用。

如何重构这段代码?

【问题讨论】:

    标签: javascript reactjs getderivedstatefromprops


    【解决方案1】:

    我认为,一种可能的方法是:

    let iFrameRefs = {}
    
    class IFrameComponent extends React.Component {
        static getDerivedStateFromProps (props) {
            if (iFrameRefs[props.id]) {
                const html = getHTMLFromContent();
                const fdoc = iFrameRefs[props.id].contentDocument;
                fdoc.write(html);
            }
            return null
        }
    
        shouldComponentUpdate() {
            return false;
        }
    
        render() {
            return (<iframe sandbox="..." ref={f => iFrameRefs[this.props.id] = f} />);
        }
    }
    

    现在从父组件向每个组件传递唯一的 id。也可以在IFrameComponent管理id。

    <IFrameComponent id='1' />
    <IFrameComponent id='2' />
    

    【讨论】:

    • 确实,这行得通,虽然我觉得把我的 refs 放在我的对象之外不太舒服。旁注:为了帮助未来的读者,您能否在getDerivedStateFromProps 中添加if(iFrame &amp;&amp; (props.content !== state.content))return {content: props.content},以体现前者的if(this.props.content !== nextProps.content)
    • 对不起,我不得不接受你的回答,因为它有一个重大缺陷:如果组件被父级多次渲染,所有组件只会填充一个 iFrame :(
    • 我意识到我的评论根本不准确。我的意思是:如果父组件渲染多个 IFrameComponent 实例,那么所有这些组件将共享相同的 IFrame 引用。
    • 是的,我也想到了那个解决方案,它会起作用,但感觉完全不对,是吗?
    猜你喜欢
    • 2021-10-12
    • 2020-01-21
    • 2021-03-09
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2012-01-29
    • 2013-06-11
    相关资源
    最近更新 更多