0

次のようなページがあります。

ここに画像の説明を入力

行の編集ボタンをクリックすると、コンポーネントは選択されたエンティティをその行に設定し、それ自体を「編集」モードにすることになっています。

ただし、右上にボックス (ここでは toast と呼ばれるコンポーネント) を表示する場合、モードはnull最初のクリックで評価されます。

ここに画像の説明を入力

コードは次のとおりです。

import React, { Component } from 'react';

import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';

import 'primereact/resources/themes/luna-blue/theme.css';
import 'primereact/resources/primereact.min.css';
import 'primeicons/primeicons.css';

const modes =
{
    VIEW:   'VIEW',
    ADD:    'ADD',
    EDIT:   'EDIT',
    REMOVE: 'REMOVE'
}

class TestManager extends Component
{
    constructor()
    {
        super();

        let persons = [
            {
                "id": 3,
                "zipCode": "",
                "cityName": "",
                "streetName": "",
                "houseNbr": "",
                "firstName": "Ahmed",
                "lastName": "Al-Thiab",
                "gender": "MALE",
            },
            {
                "id": 4,
                "zipCode": "",
                "cityName": "",
                "streetName": "",
                "houseNbr": "",
                "firstName": "Stefan",
                "lastName": "Antalovics",
                "gender": "MALE",
            },
            {
                "id": 20,
                "zipCode": "",
                "cityName": "",
                "streetName": "",
                "houseNbr": "",
                "firstName": "Christian",
                "lastName": "Attina",
                "gender": "MALE",
            },
            {
                "id": 15,
                "zipCode": "",
                "cityName": "",
                "streetName": "",
                "houseNbr": "",
                "firstName": "Filmon",
                "lastName": "Berhane",
                "gender": "MALE",
            },
            {
                "id": 2,
                "zipCode": "64895",
                "cityName": "Darmstadt",
                "streetName": "",
                "houseNbr": "",
                "firstName": "Johannes",
                "lastName": "Loczewski",
                "gender": "MALE",
            },
            {
                "id": 1,
                "zipCode": "22880",
                "cityName": "Wedel",
                "streetName": "Rosengarten",
                "houseNbr": "6",
                "firstName": "Karsten",
                "lastName": "Wutzke",
                "gender": "MALE",
            }
        ]
        
        this.state = {entities: persons,
                      selectedEntity: null,
                      mode: null};
        
        this.onRowEdit = this.onRowEdit.bind(this);
        this.onRowRemove = this.onRowRemove.bind(this);
        
        this.actions = this.actions.bind(this);
    }
    
    render()
    {
        var header = "Person Manager (" + this.state.entities.length + ")"

        return (
            <div style={{ maxWidth: 1000, marginLeft: "auto", marginRight: "auto", marginTop: 10, marginBottom: 10 }}>
                
                <Toast ref={(el) => this.toast = el} />
                
                <DataTable value={this.state.entities}
                           header={header}
                           dataKey="id"
                           selection={this.state.selectedEntity}
                           selectionMode="single"
                           sortField='lastName'
                           sortOrder={1}
                           resizableColumns
                           columnResizeMode="fit"
                           className="p-datatable-striped">
                    <Column field="id" header='ID' sortable style={{width:'7.5%'}} />
                    <Column field="gender" header='Sal.' body={this.salutation} sortable style={{width:'10%'}} />
                    <Column field='lastName' header='Last Name' sortable style={{width:'15%'}} />
                    <Column field='firstName' header='First Name' sortable style={{width:'15%'}} />
                    <Column field='streetName' header='Street' body={this.street} sortable style={{width:'20%'}} />
                    <Column field='zipCode' header='ZIP' sortable style={{width:'10%'}} />
                    <Column field='cityName' header='City' sortable style={{width:'10%'}} />
                    <Column field="actions" body={this.actions} style={{width:'12.5%'}} />
                </DataTable>
            </div>
        );
    }

    actions(rowData)
    {
        return (
            <>
                <div style={{textAlign: "center"}}>
                    <Button icon="pi pi-pencil"
                            tooltip="Edit"
                            onClick={() => this.onRowEdit(rowData)}
                            className="p-button-sm p-button-raised p-button-rounded p-button-outlined" />
                    <Button icon="pi pi-trash"
                            tooltip="Remove"
                            className="p-button-sm p-button-raised p-button-rounded p-button-outlined"
                            onClick={() => this.onRowRemove(rowData)}
                            style={{marginLeft: 5}} />
                </div>
            </>
        );
    }

    onRowEdit(rowData)
    {
        this.setState({selectedEntity: rowData});
        this.setState({mode: modes.EDIT});

        console.log("Last name: " + rowData.lastName);
        console.log("Mode: " + this.state.mode);

        this.toast.show({ severity: 'info', summary: 'Editing Person', detail: 'Name: ' + rowData.lastName + ", " + this.state.mode, life: 3000 });
    }

    onRowRemove(rowData)
    {
        this.setState({selectedEntity: rowData});
        this.setState({mode: modes.REMOVE});

        this.toast.show({ severity: 'info', summary: 'Removing Person', detail: 'Name: ' + rowData.lastName + ", " + this.state.mode, life: 3000 });
    }

    salutation(rowData)
    {
        var gender = rowData['gender'];

        if ( gender )
        {
            switch( gender )
            {
                case "MALE":
                    return "Mr";
                
                case "FEMALE":
                    return "Mrs";
                
                default:
                    return "Error";
            }
        }

        return null;
    }

    street(rowData)
    {
        var streetName = rowData['streetName'];
        var houseNumber = rowData['houseNbr'];

        return houseNumber ? streetName + " " + houseNumber : streetName;
    }
}

export default TestManager;

質問:

ここで何が問題なのですか?

これによれば

React は状態更新の順序を維持しますか?

メソッド コールバック、別名イベント ハンドラー、モードの更新に問題はないはずです。

onRowEdit(rowData)
{
    this.setState({selectedEntity: rowData});
    this.setState({mode: modes.EDIT});

    console.log("Last name: " + rowData.lastName);
    console.log("Mode: " + this.state.mode);

    this.toast.show({ severity: 'info', summary: 'Editing Person', detail: 'Name: ' + rowData.lastName + ", " + this.state.mode, life: 3000 });
}

this.state.mode常にnull最初のクリックです。その後のクリックでは、どの行でも正しいモードが表示されます。

なんで?

これを修正するにはどうすればよいですか?

ところで:this.state.selectedEntityトーストを使ったオンラインnullも同様です。

私はこれを理解するのに苦労しています。-> 自己学習者

4

3 に答える 3