【问题标题】:React DOM not re-rendering/updating after state changeReact DOM 在状态更改后不会重新渲染/更新
【发布时间】:2020-03-19 14:44:44
【问题描述】:

当前状态对象是这样的:

this.state = {
        loadedPostList: [],
        top: 0,
        end: 0,
        thresh: 20,
        page: 0,
        loadingPostList: false,
        filter: [],
        lazying: false
};

我正在利用一些反应生命周期方法来控制我的 redux 商店更新和数据流:

shouldComponentUpdate(nextProps, nextState) {
    return this.props.posts.loadedPosts !== nextProps.posts.loadedPosts || this.state.loadedPostList !== nextState.loadedPostList;
}

componentDidUpdate(prevProps) {
    let { loadedPosts, changeEvent, updatedId, deleteId } = this.props.posts;
    if(prevProps.posts.loadedPosts !== loadedPosts) {

        switch(changeEvent) {
            case 'insert':
                if(this.state.top === 0) {
                    this.refreshList();
                }
                console.log('new post in thread...');
                break;
            case 'update':
                this.refreshList();
                console.log('post updated in thread...');
                break;
            case 'delete':
                this.refreshList();
                console.log('post deleted in thread...');
                break;
            default:
                break;
        }
    }
}

refreshList = () => {
    let newList = this.props.posts.loadedPosts.slice(this.state.top, this.state.end);
    this.setState({
        loadedPostList: [...newList]
    }, () => {
        console.log('refreshed post list')
    })
}

在渲染函数中,我将 this.state.loadedPostList 的元素映射到 PostList 组件。问题是,当我的 redux 存储更新以及随后我的 this.state.loadedPostList 时,重新渲染中的映射不会更新以显示更新后的数组。登录到控制台并通过 redux 开发工具观察 redux 操作和存储表明数组确实在正确更新,并且诸如 refreshList() 之类的函数正在正常工作。但是,问题仍然存在,DOM 没有根据状态更改重新渲染/更新。渲染函数:

render() {
    return (
        <div id="question-list-wrapper">
            {
                this.state.loadingPostList || this.state.lazying ? 

                <MiniViewLoader textToRender="Loading questions..."/>

                :


                <div id="question-list-inner-wrapper">

                    <div id="question-list-inner-wrapper-nav">
                        <h1 className="text" id='inner-wrapper-nav-header'> Recent Questions </h1>
                    </div>
                    {
                        this.state.loadedPostList.length < 1 ?  <h1 className="no-questions-text">No questions availabe</h1> : ""
                    }
                    {
                        this.state.loadedPostList.map((post, index) => {
                            return (
                                <PostSlot idx={index} key={index+""} postData={post}/>
                            )
                        })
                    }

                    <div id="question-list-write-btn" alt="">
                        <span></span>
                        <WritePostButton />
                    </div>

                </div>


            }
        </div>
    )
}

(编辑)如果有帮助,请提供更多信息。存在问题的组件正在由另一个组件的 render() 函数内的反应路由器 Switch 包装器呈现。

其他组件:

render() {

    return(
        <div className="page-wrapper">
            {
                this.state.settingUp ?

                <FullPageLoaderWithText textToRender="Setting things up for you..."/>
                :

                <div id="main-hoc-wrapper-inner-wrapper">

                    <div id="main-hoc-nav-bar" className="item-a">
                        <span id="main-hoc-nav-logo" className="main-hoc-nav-elem">
                            PA
                        </span>
                        <span id="main-hoc-nav-search" className="main-hoc-nav-elem">
                            <input type="text" placeholder="Search..." className="placeholderEdit"/>
                        </span>
                    </div>

                    <div id="main-hoc-sidebar" className="item-c">
                        <span className="main-hoc-sidebar-tabs">{this.props.user.data}</span>

                        <span className="main-hoc-sidebar-tabs">tags</span>

                        <span className="main-hoc-sidebar-tabs">community</span>

                        <span className="main-hoc-sidebar-tabs">opportunities</span>
                    </div>

                    <div id="main-hoc-main-view" className="item-b">
                        <Switch>
                            {/* <Route path="/:param1/:param2/path" component={QuestionList} /> */}
                            <Route path="/:param1/:param2/path" render={() => <QuestionList connect={socket}/>} />

                        </Switch>
                    </div>

                    <div id="main-hoc-right-bar" className="item-d">
                        Blog posts & ads
                    </div>

                </div>
            }


        </div>
    )
}

【问题讨论】:

    标签: javascript reactjs redux react-redux react-router


    【解决方案1】:

    我认为问题在于您的if 条件,您无法将两个数组与!== 进行比较。

    例子:

    var t = [1,2,3];
    var f = [1,2,3];
    
    if (t !== f) {
      console.log("different");
    } else {
      console.log("same");
    }
    
    // by your logic the output should be "same"
    // but it will not be
    // because internally they both are object and we cannot compare
    // two objects using `===` operator.
    // you will have to loop through and check for difference
    
    
    // or better let REACT HANDLE SUCH THINGS
    
    

    【讨论】:

      【解决方案2】:

      问题出在这一行

      let newList = this.props.posts.loadedPosts.slice(this.state.top, this.state.end);,

      this.state.topthis.state.end 都是 0,所以它总是会返回一个空数组,请确保在每次刷新后更新顶部和末尾。

      【讨论】:

      • this.state.top 和 this.state.end 工作正常;刷新功能实际上并不刷新页面/列表;它只是决定更大列表的更新部分是否在顶部和结束的范围(索引范围)内。刷新函数运行后,数组会正确更新(我已经通过控制台日志验证了这一点,并观察了 redux 开发工具中的状态变化)。问题在于,映射此数组元素的渲染中的 ui 不会重新渲染或更新,即使在数组中的元素更改之后(除非手动刷新页面)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2021-05-19
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多