React DOM 在状态更改后不会重新渲染/更新 [英] React DOM not re-rendering/updating after state change

查看:33
本文介绍了React DOM 在状态更改后不会重新渲染/更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前状态对象是这样的:

this.state = {加载后列表:[],顶部:0,结束: 0,阈值:20,页数:0,loadingPostList: 假,筛选: [],懒惰:假};

我正在使用一些 react 生命周期方法来控制我的 redux 存储更新和数据流:

shouldComponentUpdate(nextProps, nextState) {返回 this.props.posts.loadedPosts !== nextProps.posts.loadedPosts ||this.state.loadedPostList !== nextState.loadedPostList;}componentDidUpdate(prevProps) {让{loadedPosts,changeEvent,updatedId,deleteId } = this.props.posts;if(prevProps.posts.loadedPosts !==loadedPosts) {开关(更改事件){案例插入":if(this.state.top === 0) {this.refreshList();}console.log('线程中的新帖子...');休息;案例更新":this.refreshList();console.log('帖子在线程中更新...');休息;案例删除":this.refreshList();console.log('帖子已在线程中删除...');休息;默认:休息;}}}refreshList = () =>{让 newList = this.props.posts.loadedPosts.slice(this.state.top, this.state.end);this.setState({加载后列表:[...新列表]}, () =>{console.log('刷新后的帖子列表')})}

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

render() {返回 (<div id="问题列表包装器">{this.state.loadingPostList ||this.state.lazying ?<MiniViewLoader textToRender="正在加载问题..."/>:<div id="question-list-inner-wrapper"><div id="question-list-inner-wrapper-nav"><h1 className="text" id='inner-wrapper-nav-header'>最近的问题 </h1>

{this.state.loadedPostList.length <1 ?<h1 className="no-questions-text">没有可用的问题</h1>:""}{this.state.loadedPostList.map((post, index) => {返回 (<PostSlot idx={index} key={index+""} postData={post}/>)})}<div id="question-list-write-btn" alt="提问"><span>提出问题</span><WritePostButton/>

}

)}

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

其他组件:

render() {返回(<div className="page-wrapper">{this.state.settingUp ?<FullPageLoaderWithText textToRender="正在为您设置..."/>:<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">公共广播</span><span id="main-hoc-nav-search" className="main-hoc-nav-elem"><input type="text" placeholder="搜索..." className="placeholderEdit"/></span>

<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">标签</span><span className="main-hoc-sidebar-tabs">社区</span><span className="main-hoc-sidebar-tabs">机会</span>

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

<div id="main-hoc-right-bar" className="item-d">博客文章和广告

}

)}

解决方案

我认为问题在于你的 if 条件,你不能用 !== 比较两个数组.

示例:

var t = [1,2,3];var f = [1,2,3];如果 (t !== f) {console.log("不同");} 别的 {console.log("相同");}//根据你的逻辑,输出应该是相同的"//但它不会//因为在内部它们都是对象,我们无法比较//使用 `====` 运算符的两个对象.//你将不得不循环并检查差异//或者更好地让 REACT 处理这些事情

The current state object is this:

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

I'm utilising some react lifecycle methods to control my redux store updates, and dataflow:

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

And in the render function, I'm mapping the elements of this.state.loadedPostList to PostList components. The problem is that when my redux store updates, and subsequently my this.state.loadedPostList, the mapping in re-render doesn't update to show the updated array. Logging to the console and observing the redux actions and store via redux dev tools show that the array is indeed updating correctly, and the functions such us refreshList() are working as they should. However, the problem remains with the DOM not re-rendering/updating according to the state changes. The render function:

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="Ask Question">
                        <span>Ask Question</span>
                        <WritePostButton />
                    </div>

                </div>


            }
        </div>
    )
}

(EDIT) Further information if it helps. The component with the issue is being rendered by a react router Switch wrapper inside the render() function of another component.

The Other Component:

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

解决方案

I think the problem is your if condition, you cannot compare two array with !==.

Example:

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

这篇关于React DOM 在状态更改后不会重新渲染/更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆