javascript - 为什么子组件的状态不断清除?

标签 javascript reactjs

我有多层 React 组件,用于从音乐服务 API 获取嵌入,包括一个点击 API 来填充嵌入的高阶组件。我的问题是我的最低级别的子组件不会改变状态。我基本上希望填充的嵌入(最低级别的组件)显示一个专辑封面,单击它后消失(显示 iframe),并且其状态保持稳定,除非更高的 props 发生任何变化(当该组件显示时,有除了焦点更高之外应该没有其他状态变化)。代码如下:

父级:

return (
            /*...*/
                <Embed
                    embed={this.props.attributes.embed}
                    cb={updateEmbed}
                />
            /*...*/

第一个 child (上面):

render() {
        const {embed, className, cb} = this.props;
        const {error, errorType} = this.state;
        const WithAPIEmbed = withAPI( Embed );

        /*...*/

        return <WithAPIEmbed
            embed={embed[0]}
            className={className}
            cb={cb}
        />;
        /*...*/

使用API​​:

/*...*/
        componentWillMount() {
            this.setState( {fetching: true} );
        }

        componentDidMount() {
            const {embed} = this.props;

            if ( ! embed.loaded ) {
                this.fetchData();
            } else {
                this.setState( {
                    fetching: false,
                    error: false,
                } );
            }
        }

        fetchData() {
           /*... some API stuff, which calls the callback in the top level parent (cb()) setting the embed prop when the promise resolves -- this works just fine ...*/ 
        }

        render() {
            const {embed, className} = this.props;
            const {fetching, error, errorType} = this.state;

            if ( fetching ) {
                /* Return some spinner/placeholder stuff */
            }

            if ( error ) {
                /* Return some error stuff */
            }

            return (
                <WrappedComponent
                    {...this.props}
                    embed={embed}
                />
            )
        }

最后一个我感兴趣的 child :

constructor() {
        super( ...arguments );
        this.state = {
            showCover: true,
        };
    }

    render() {
        const {embed, setFocus, className} = this.props;
        const {showCover} = this.state;

        if ( showCover ) {
            return [
                <div key="cover-image" className={classnames( className )}>
                    <figure className='cover-art'>
                        <img src={embed.coverArt} alt={__( 'Embed cover image' )}/>
                        <i onClick={() => {
                            this.setState( {showCover: false,} );
                        }}>{icon}</i> // <-- Play icon referenced below.
                    </figure>
                </div>,
            ]
        }

        return [
            <div key="embed" className={className}>
                    <EmbedSandbox
                        html={iframeHtml}
                        type={embed.embedType}
                        onFocus={() => setFocus()}
                    />
            </div>,
        ];
    }

我的问题是,单击播放图标应该清除专辑封面并显示 iframe 嵌入,但即使单击正在注册,状态也不会改变(或者改变然后变回来)。我相信这是因为更高级别的组件正在安装/卸载并以其默认状态重新实例化该组件。我可以将此状态移到树上或使用 Flux 之类的东西,但我真的觉得我不需要这样做,而且我在这里缺少一些基本的东西。

最佳答案

问题在于 const WithAPIEmbed = withAPI( Embed ); 位于 render 方法内部。这会在每个渲染上创建一个新的 WithAPIEmbed 对象,该对象将被重新安装,并清除下面的任何状态。将其从类定义中取出使其稳定并解决问题。

关于javascript - 为什么子组件的状态不断清除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49342535/

相关文章:

javascript - 如何强制同步 soundcloud javascript sdk 调用?

javascript - VueJS 2 Uncaught ReferenceError : _ is not defined with debounce

reactjs - Material-ui v.1 - 使用主题定义组件的背景

reactjs - 如何从react.js中的父级调用功能组件中子级的功能?

html - 在自定义下拉列表中隐藏额外的文本

javascript - 自定义图表中的标题 DevExtreme

javascript - Javascript 中的类字段和属性有什么区别

javascript - 如何根据html页面更改英雄形象?

reactjs - 捆绑时未定义 React

javascript - 过滤对象数组并设置状态数组变量