Reactjs - функция, вызываемая в render (), вызывается несколько раз при нажатии на вкладку - PullRequest
1 голос
/ 27 апреля 2020

Вчера я начал свой первый проект Reactjs и столкнулся с проблемой.

Приложение использует React Bootstrap - в основном только компоненты "Tab" и "Tabs" прямо сейчас, так как а также jQuery datatables.

Я пытаюсь сделать следующее:

  1. У меня есть пара вкладок на моем пользовательском интерфейсе
  2. Не загружать обе вкладки загружать вкладку сразу после нажатия. Я сделал это, добавив mountOnEnter = {true} в вкладки div
  3. При первой загрузке вкладки инициализируем объект базы данных. Если он не создан, просто вызовите ajax .reload ()

Итак, я понял, что могу установить для переменной состояния значение true при нажатии на вкладку, а затем передать эту переменную состояния в Datatable Компонент как свойство. Затем компонент Datatable может просто проверить состояние и создать таблицу данных или просто сделать еще один ajax вызов, чтобы обновить sh данные.

TabsExample компонент

import React, { Component } from 'react'
import Tabs from 'react-bootstrap/Tabs'
import Tab from 'react-bootstrap/Tab'
import {Datatable} from '../datatable/Datatable'
import './TabsExample.css'

export class TabsExample extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            'key': 'tab1',
            'hasInitialised': false
        }
        this.handleSelect = this.handleSelect.bind(this);
    }

    // Update the state when a tab is clicked
    handleSelect(selectedTab) {
        this.setState({key: selectedTab, hasInitialised: true});
    }

    render() {
        return (
            <div class="tabs-container">
                <Tabs defaultActiveKey={this.state.key} onSelect={this.handleSelect} mountOnEnter={true}>
                    <Tab eventKey="tab1" title="Tab 1">
                        <Datatable initStatus={this.state.hasInitialised} tabName={this.state.key}>
                        </Datatable>
                    </Tab>
                    <Tab eventKey="tab2" title="Tab 2">
                        <Datatable initStatus={this.state.hasInitialised} tabName={this.state.key}>
                        </Datatable>
                    </Tab>
                </Tabs>
            </div>
        );
    }
}

Datatable компонент

Примечание. Затем я обнаружил, что вы можете использовать componentDidMount () - который, как мне кажется, срабатывает при первом монтировании компонента, а затем никогда, поэтому имеет смысл поместить сюда код инициализации. Еще одно примечание: я еще не реализовал вызов ajax, поэтому сейчас я просто распечатываю свойства, чтобы увидеть, установлено ли для "initStatus" значение true.

import React, { Component } from 'react'
import '../../../node_modules/datatables.net-bs4/css/dataTables.bootstrap4.min.css'
import './Datatable.css'

const $ = require('jquery')
$.DataTable = require('datatables.net-bs4')

export class Datatable extends Component {

    someFunc() {
        // -----------------------------------------------------------
        // this gets called 4 times every time a tab is clicked???
        // -----------------------------------------------------------
        console.log(this.props);

        // I want to do something like this
        // if (this.props.initStatus)
            // ajax.reload()
    }

    componentDidMount() {
        this.$el = $(this.el)

            this.$el.DataTable(
                {
                    lengthMenu: [ 15, 50, 75 ],
                    columns: [
                        { title: "Name" },
                        { title: "Position" },
                        { title: "Office" },
                        { title: "Extn." },
                        { title: "Start date" },
                        { title: "Salary" }
                    ]
                }
            )
    }

    componentWillUnmount() {
        this.$el.DataTable.destroy(true)
    }

    render() {
        this.someFunc()
        return <div>
            <div class="table-container">
                <table className="table table-striped table-bordered" width="100%" ref={el => this.el = el}>
                </table>
            </div>
        </div>
    }
} 

Так что пока работает, и я вижу, что значение "true", как я и ожидал, я не понимаю, почему функция вызывается 4 раза. Очевидно, я не хочу этого, так как при реализации вызова ajax он будет выполнять 4 запроса.

Вывод при переходе с вкладки 1 на вкладку 2

{initStatus: true, tabName: "tab2"}
{initStatus: true, tabName: "tab2"}
{initStatus: true, tabName: "tab2"}
{initStatus: true, tabName: "tab2"}

с вкладки 2 на вкладку выдает тот же вывод

Кто-нибудь знает, почему это происходит?

...