@FreeArcher
Senior 1С; php, JS Starter

Почему компонент перерисовывается 3 раза?

import React from 'react';
import './BkItem.css';

export default class BkItem extends React.Component {
    constructor(props) {
        super(props)

        this.actionClickBk = this.actionClickBk.bind(this)

        console.log("BkItem - constructor")
    }

    getClassColor() {
        const colorInd = Math.round(Math.random() * 10)
        const className = { backgroundColor: `var(--bg-color${colorInd})` }
        return className
    }

    actionClickBk(url, evt) {
        evt.preventDefault();
        //window.open(url).focus();
        window.open(url, "_self");
    }

    componentWillMount() {
        console.log("BkItem - componentWillMount")
    }
    componentDidMount() {
        console.log("BkItem - componentDidMount")
    }

    render() {
        const { currentBk, title } = this.props
        const style = this.getClassColor()
        console.log("BkItem")

        return (
            <div
                className="bk-item"
                style={style}
                onClick={(evt) => this.actionClickBk(currentBk.url, evt)}
            >
                {title}
            </div>
        )
    }
}

5cb92573753e4870511286.png
Рендерится 3 раза. Родитель выполняется 1 раз.
Если использовать PureComponent то 2 раза. Но всё равно раз лишний.
5cb925d4e20db412002934.png

Код родителя
import React, { Component } from 'react';

import Modal from 'react-bootstrap/Modal'

import './BkModal.css';

import BkFolder from './BkFolder'
import BkItem from './BkItem'

export default class BkOpenFolder extends React.PureComponent {
    constructor(props) {
        super(props)

        this.state = {
            isOpenFolder: this.props.isOpenFolder,
        }
    }

    setOpenFolder = () => {
        this.setState({ isOpenFolder: !this.state.isOpenFolder })
        this.props.setOpenFolder()
    }
    closeOpenFolder = () => {
        this.setState({ isOpenFolder: false })
        this.props.setOpenFolder()
    }

    render() {
        console.log("BkModal")
        const { title, bkFolder } = this.props
        let renderComponent = []

        if (!this.state.isOpenFolder) return null;

        if (!bkFolder.children) {
            renderComponent.push(
                <BkItem
                    title={title}
                />)
        } else {

            for (const currentBk of bkFolder.children) {

                if (!currentBk.children) {
                    renderComponent.push(
                        <BkItem
                            key={currentBk.id}
                            currentBk={currentBk}
                            title={currentBk.title}
                        />)
                } else {
                    renderComponent.push(
                        <BkFolder
                            key={currentBk.id}
                            currentBk={currentBk}
                            title={currentBk.title}
                        />
                    )
                }
            }
        }

        console.log(renderComponent)
        return (
            <Modal
                size="lg"
                aria-labelledby="contained-modal-title-vcenter"
                centered
                show={this.state.isOpenFolder}
                onHide={this.closeOpenFolder}
                animation={true}
            >
                <Modal.Header closeButton>
                    {title}
                </Modal.Header>
                <Modal.Body
                    style={{ background: "rgb(95, 110, 211)" }}
                >
                    <div >
                        <div className="bk-open-folder">
                            {renderComponent}
                        </div>
                    </div>
                </Modal.Body>
            </Modal>
        )
    }
}


Подскажите почему так происходит?
  • Вопрос задан
  • 601 просмотр
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Родитель выполняется 1 раз.

Родителем для ваших компонентов является не BkOpenFolder, а Modal.Body, над ним еще есть Modal. Инициирует обновление дочернего древа один из них.

Если использовать PureComponent то 2 раза. Но всё равно раз лишний.

Нет там лишнего раза, для четырех компонентов:
4 вызова конструктора
4 вызова componentWillMount
4 вызова render
4 вызова componentDidMount

Для того чтобы убрать лишние перерисовки компонентов можно:
1. Использоавать PureComponent.
2. Реализовать метод жизненного цикла shouldComponentUpdate.

Компоненты обернутые в вызов connect из пакета react-redux, так же не обновляются при перерисовке древа, если входящие свойства не изменились.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы