Реакция DOM не повторная рендеринг / обновление после изменения состояния - PullRequest
1 голос
/ 19 марта 2020

Текущий объект состояния выглядит следующим образом:

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

Я использую некоторые методы жизненного цикла реагирования для управления обновлениями моего магазина избыточности и потоком данных:

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. Проблема заключается в том, что когда обновляется мое хранилище редуксов, а затем и мой this.state.loadedPostList, отображение при повторном рендеринге не обновляется, чтобы показать обновленный массив. Вход в консоль и наблюдение за действиями приращения и сохранением с помощью средств управления приставкой показывает, что массив действительно обновляется правильно, а функции, такие как 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="Ask Question">
                        <span>Ask Question</span>
                        <WritePostButton />
                    </div>

                </div>


            }
        </div>
    )
}

(EDIT) Дополнительная информация, если это поможет. Компонент с проблемой воспроизводится маршрутизатором реакции. Оболочка Switch внутри функции render () другого компонента.

Другой компонент:

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

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Я думаю, что проблема в вашем 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

0 голосов
/ 19 марта 2020

проблема в этой строке

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

this.state.top и this.state.end равны 0, поэтому он всегда будет возвращать пустой массив, убедитесь, что вы обновляете верх и конец после каждого refre sh.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...