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


Подскажите почему так происходит?
  • Вопрос задан
  • 691 просмотр
Решения вопроса 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, так же не обновляются при перерисовке древа, если входящие свойства не изменились.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
28 нояб. 2024, в 21:25
5000 руб./за проект
28 нояб. 2024, в 18:46
3000 руб./за проект
28 нояб. 2024, в 17:46
10000 руб./за проект