! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

React Redux 앱에서 편집 가능한 데이터그리드 만드는 방법 > 블로그 & Tips

본문 바로가기

React Redux 앱에서 편집 가능한 데이터그리드 만드는 방법

페이지 정보

작성자 GrapeCity 작성일 2020-04-01 00:00 조회 3,253회 댓글 0건

본문

개발자들은 Redux를 좋아합니다.


Redux는 최근 널리 사용되는 애플리케이션 아키텍처이며 특히 React 커뮤니티에서 사용됩니다. Redux는 개발자들이 단방향 데이터 흐름을 사용하고, 전역 Redux Store의 한 곳에서 Redux reducer를 사용하여 데이터에 변경사항을 적용하도록 합니다. 또한, 이 아키텍처는 애플리케이션을 보다 안정적이고 유지보수하기 쉽게 만들어줍니다. 이것이 바로 많은 개발팀이 Redux를 애플리케이션 아키텍처의 기반으로 선택하는 이유입니다.


이 패러다임의 핵심 요구 사항 중 하나는 데이터를 변경할 수 없는 상태로 유지하는 것입니다. 데이터에 대한 모든 변경은 Redux reducer에서 기존 데이터를 복제하여 수행해야 합니다. 배열에 항목을 추가해야 하는 경우 새 항목을 추가하기 위해 배열의 복제본을 만들어야 합니다. 항목 속성을 변경해야 하는 경우에는 속성의 새 값을 포함하는 복제본을 만들어야 합니다. 기존 배열과 객체를 변경해서는 안됩니다!


애플리케이션은 편집 가능한 DataGrid를 좋아합니다.


Redux를 사용하는 동시에 개발자는 DataGrid 컴포넌트를 애플리케이션 UI의 일부로 사용하고자 합니다. DataGrid를 사용하면 애플리케이션 사용자는 복잡한 테이블 형식의 데이터를 편리하고 간결한 형태로 볼 수 있을 뿐만 아니라 정렬, 그룹화 및 필터링과 같은 데이터 변환을 효율적으로 수행할 수 있기 때문에 애플리케이션에서 DataGrid는 핵심적인 요소입니다. 이를 통해, 사용자는 Microsoft Excel에서 데이터를 편집하는 것과 동일한 방식으로 데이터를 편집 할 수 있습니다 .


Excel에서는 DataGrid 셀에서 바로 항목 값을 편집할 수 있습니다. 항목을 추가 또는 삭제할 수 있으며, Excel 또는 다른 DataGrid에서 데이터를 복사하여 붙여 넣고, 선택한 여러 셀을 지울 수도 있습니다.


이것이 많은 모던 웹에서 데이터그리드가 필수적인 이유입니다.


편집 가능한 DataGrid는 Redux를 좋아하지 않습니다.


Redux 기반의 고급 애플리케이션 아키텍처를 사용하면서, 애플리케이션 UI의 일부로 편집 가능한 DataGrid를 사용하길 원한다면, 딜레마에 직면하게 됩니다.


여기서 문제는 DataGrid 컴포넌트가 바인딩 된 데이터를 직접 변경하도록 설계되었다는 것입니다. "일반적인" 애플리케이션의 경우에는 전혀 문제가 되지 않지만, Redux에서는 데이터를 변경할 수 없는 상태로 유지해야 하기 때문에 작동하지 않습니다.


Redux를 원한다면 편집 가능한 DataGrid를 포기해야 하며, 그렇게 되면 애플리케이션에 의해 제공되는 사용자 경험 개선이 어려워집니다.


고급 애플리케이션 아키텍처는 고급 UI 컴포넌트를 사용할 수 없으며, 이 문제를 해결할 수 있는 확실한 방법은 없습니다. Immer 및 Immutable과 같은 특수 라이브러리를 사용하면 Redux reducer에서 발생할 수있는 문제를 해결할 수 있지만 특정 라이브러리에서는 해결할 수 없습니다.


그렇다면 멋진 UI를 포기해야 할까요? FlexGrid를 사용하면 포기하지 않아도 됩니다!


FlexGrid는 Redux를 좋아합니다.


Wijmo 팀에서는 고객들의 도움을 받아 이 문제를 인식하여 ImmutabilityProvider라는 사용하기 쉬운 FlexGrid 확장 컴포넌트를 소개합니다FlexGrid 컴포넌트에 적용되면 다음과 같은 방식으로 동작이 변경됩니다.


  • 모든 데이터 편집 기능을 유지하면서 DataGrid가 기본 데이터를 변경하지 못하게 합니다. 즉, 사용자는 가능한 모든 방법으로 FlexGrid를 통해 데이터를 편집할 수 있지만 Redux Store의 기본 데이터 배열은 변경할 수 없습니다.

  • 사용자가 FlexGrid에서 데이터를 편집할 때 ImmutabilityProvider는 변경에 대한 정보가 포함된 특수 이벤트를 발생시켜 데이터 변경 작업을 Redux Store에 보내는 데 사용할 수 있습니다.

이제 어떻게 작동하는지 살펴보겠습니다.


ImmutabilityProvider


컴포넌트의 render 메소드에 데이터 바인딩 된 FlexGrid 컨트롤을 추가하는 가장 간단한 JSX는 다음과 같습니다.


<FlexGrid itemsSource={this.props.items}>
</FlexGrid>


이 DataGrid는 사용자가 DataGrid를 통해 데이터를 편집할 때 itemsSource 속성에 바인딩 된 데이터 배열을 변경합니다이 동작을 변경하고 FlexGrid가 기본 데이터 변경을 강제로 중단하도록 하려면 다음과 같이 ImmutabilityProvider React 컴포넌트를 FlexGrid 컴포넌트에 중첩시킵니다.


<FlexGrid>
    <ImmutabilityProvider 
        itemsSource={this.props.items}
        dataChanged={this.onGridDataChanged} />
</FlexGrid>


또한 dataChanged 이벤트에 대한 처리기를 정의하였는데, dataChanged 이벤트는 사용자가 편집한 결과인 데이터그리드에서 발생할 수 있는 다음의 세 가지 유형의 데이터 변경에 대해 알려줍니다. 


  • 기존 항목의 속성 값 변경
  • 새로운 항목 추가
  • 항목 삭제

이 이벤트가 트리거되면 시각적으로는 모든 데이터가 변경된 것처럼 보이지만 기본 items 배열은 변경되지 않은 상태로 유지됩니다. (배열 자체와 항목 속성 모두)


이 이벤트를 사용하여 해당 데이터 변경 작업을 Redux Store에 보내 사용자가 변경한 내용을 전역 애플리케이션 상태에 적용합니다. 이벤트 핸들러는 다음과 같습니다.


onGridDataChanged(s: ImmutabilityProvider, e: DataChangeEventArgs) {
    switch (e.action) {
        case DataChangeAction.Add:
            this.props.addItemAction(e.newItem);
            break;
        case DataChangeAction.Remove:
            this.props.removeItemAction(e.newItem, e.itemIndex);
            break;
        case DataChangeAction.Change:
            this.props.changeItemAction(e.newItem, e.itemIndex);
            break;
        default:
            throw 'Unknown data action'
    }
}


FlexGrid에서 발생한 데이터 변경 유형(Add , Remove 또는 Change)에 따라 이벤트 핸들러는 해당 action을 Redux Store의 Reducer에 전달 합니다. Redux Store의 Reducer는 전송된 변경 사항을 포함하는 배열의 복제본으로 전역 상태를 업데이트합니다. 이 배열은 ImmutabilityProvider.itemsSource 속성에 직접 바인딩 되므로 Redux Store의 Reducer는 변경 사항을 감지하고 FlexGrid가 Store에서 발생한 변경 사항을 반영하도록 해당 내용을 새로 고칩니다.



복잡한 데이터 흐름처럼 보이지만, 꽤 큰 데이터에서도 성능이 좋습니다. 사용자가 변경한 내용은 거의 즉시 적용됩니다.


이 접근 방식을 사용하면 Redux 애플리케이션에서 DataGrid를 데이터 편집 컨트롤로 사용하는 것이 거의 단일 값 입력 컨트롤(예 : 기본 input 요소 또는 특수한 InputNumber , InputDate 등)을 사용하는 것처럼 간단해집니다. 전역 상태 속성에 컨트롤 값 속성을 지정하고 컨트롤의 "값이 변경된" 이벤트에서 새로운 값을 가진 작업을 전달합니다.


React-Redux 추가 세부 사항


이제 DataGrid를 사용하여 Redux Store에서 배열을 표시하고 편집하는 간단한 애플리케이션을 만드는 방법에 대한 자세한 내용을 살펴 보겠습니다. 데모 목적으로 이 샘플 사용하겠습니다 . 이 샘플은 이 포스팅에서 다루고 있는 문제에 대한 해결책을 보다 쉽게 이해할 수 있도록 매우 간단하게 만들어졌습니다. 앞으로 Redux 애플리케이션에서 사용되는 FlexGrid와 다른 Wijmo 컨트롤의 다양한 측면을 보여주는 샘플을 더 추가할 계획입니다. GrapeCity가 다루었으면 하는 특정 이슈가 있다면, 주저하지 말고 공유해주시길 바랍니다.


이 샘플은 플랫 폴더 구조를 사용하여 Wijmo 온라인 데모 사이트에 더 잘 맞습니다. 또한 샘플 설정에 대한 데모 사이트 요구 사항으로 인해 Webpack 또는 유사한 번들러 대신 SystemJS 런타임 로더를 사용하여 모듈을 로드합니다.



 


애플리케이션에는 두 개의 FlexGrid 컨트롤이 포함된 단일 뷰가 있습니다. 맨 위에 있는 것은 Redux Store에서 배열에 바인딩 된 ImmutabilityProvider 컴포넌트에 의해 제어되는 편집 가능한 datagrid입니다. 이것은 기능을 확인하기 위한 DataGrid입니다. 키보드에서 셀 값을 입력하여 편집하거나, 그리드 행 목록의 끝에 있는 "new row" 행을 사용하여 새 항목을 추가하거나, 항목을 선택하고 삭제 버튼을 눌러 항목을 삭제할 수 있습니다.


클립 보드에서 데이터를 붙여 넣거나 선택한 셀 범위에서 여러 셀 값을 지울 수도 있습니다.


데이터 그리드에 표시된 데이터 배열의 모든 항목은 Object.freeze() 함수를 사용하여 고정되어 편집을 수행할 때 DataGrid가 데이터를 변경하지 않도록 해야 합니다.


편집 외에도 열 머리글을 클릭하여 정렬하고 열 머리글을 DataGrid 위의 그룹 패널로 끌어 그룹화한 다음 열 머리글의 필터 아이콘을 클릭하여 필터링하여 필요한대로 데이터를 변환할 수 있습니다.


두번째 DataGrid는 읽기 전용입니다. ImmutabilityProvider를 사용하지 않으며 itemsSource 속성을 사용하여 Store의 배열에 직접 바인딩 됩니다. 이 DataGrid를 사용하면 최상위 DataGrid를 통해 변경한 사항이 Redux Store에 어떻게 적용되는지 확인할 수 있습니다.


상단 DataGrid 위에 메뉴가 있어 데이터 배열의 크기를 변경할 수 있습니다. 작은 배열은 변경 사항이 Store에 적용되는 방법을 확인하는 데 편리하며, 더 큰 배열을 사용하여 편집 프로세스의 성능을 평가할 수 있습니다. 실제 애플리케이션에서 예상하는 것과 유사한 몇 가지 항목을 선택하고 작동 방식을 평가할 수 있습니다.


상태


초기 애플리케이션 전역 상태는 다음과 같이 reducers.jsx 파일에 정의됩니다.


const itemCount = 5000;
const initialState = {
    itemCount,
    items: getData(itemCount),
    idCounter: itemCount
}


여기에는 무작위로 생성된 데이터가 있는 items 배열과 다음의 두가지 보조 속성이 포함됩니다.


  • itemCount : 배열의 항목 수를 정의합니다.
  • idCounter : 새로 추가된 항목의 id 속성에 할당할 고유한 id 값을 저장합니다.

items 배열은 샘플의 DataGrids로 표시한 것입니다. 배열의 모든 항목은 Object.freeze () 함수를 사용하여 고정되어 Redux의 데이터 불변성 요구 사항이 실제로 충족되도록 합니다.

 

Action


Redux action creator 함수는 actions.jsx 파일에 정의되어 있습니다.


export const addItemAction = (item) => ({
    type: 'ADD_ITEM',
    item
});

export const removeItemAction = (item, index) => ({
    type: 'REMOVE_ITEM',
    item,
    index
});

export const changeItemAction = (item, index) => ({
    type: 'CHANGE_ITEM',
    item,
    index
});

export const changeCountAction = (count) => ({
    type: 'CHANGE_COUNT',
    count
});


items 배열에서 수행되는 데이터 변경 작업을 위한 3가지 작업(ADD_ITEM, REMOVE_ITEM 및 CHANGE_ITEM)과 추가적인 CHANGE_COUNT 작업으로 인해 Store가 다른 항목 수를 가진 새로운 items 배열을 만들 수 있습니다.



모든 액션은 action creator 함수로 표현됩니다이러한 함수는 ImgridabilityProvider.dataChanged 이벤트 핸들러 (GridView 프리젠테이션 컴포넌트)에서 호출되어 DataGrid에서 작성된 데이터 변경 사항을 Store에 알립니다.


항목 변경 작업의 경우 index 속성에는 items 배열에 영향을 받는 항목의 인덱스가 포함됩니다. 그리고 item 속성은 item 객체에 대한 참조를 저장합니다. Reducer에 대해 다루고 있는 아래에서 더 자세히 알아보겠습니다.


Reducer


애플리케이션은 위에서 설명한 방법을 기반으로 애플리케이션 전역 상태에 대한 모든 업데이트를 수행하는 단일 Reducer 정의합니다reducers.jsx 파일에서 다음과 같이 구현됩니다.


export const appReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_ITEM':
            {
                // make a clone of the new item which will be added to the
                // items array, and assigns its 'id' property with a unique value.
                let newItem = Object.freeze(copyObject({}, action.item, 
                        { id: state.idCounter }));
                return copyObject({}, state, {
                    // items array clone with a new item added
                    items: state.items.concat([newItem]),
                    // increment 'id' counter
                    idCounter: state.idCounter + 1
                });
            }
        case 'REMOVE_ITEM':
            {
                let items = state.items,
                    index = action.index;
                return copyObject({}, state, {
                    // items array clone with the item removed
                    items: items.slice(0, index).concat(items.slice(index + 1))
                });
            }
        case 'CHANGE_ITEM':
            {
                let items = state.items,
                    index = action.index,
                    oldItem = items[index],
                    // create a cloned item with the property changes applied
                    clonedItem = Object.freeze(copyObject({}, oldItem, action.item));
                return copyObject({}, state, {
                    // items array clone with the updated item
                    items: items.slice(0, index).
                        concat([clonedItem]).
                        concat(items.slice(index + 1))
                });
            }
        case 'CHANGE_COUNT':
            {
                // create a brand new state with a new data
                let ret = copyObject({}, state, {
                    itemCount: action.count,
                    items: getData(action.count),
                    idCounter: action.count
                });
                return ret;
            }
        default:
            return state;
    }
}


Redux가 요구하는 것처럼 기존 항목 배열과 해당 항목의 속성을 변경하지 않습니다 항목을 추가하거나 삭제하면 이 항목이 추가되거나 제거되는 배열의 복제본이 생성됩니다. 동작이 기존 항목의 속성을 업데이트하도록 규정한 경우 업데이트된 항목이 변경된 항목의 복제본으로 대체되는 새 배열을 만듭니다.


이 복제된 항목에는 변경된 속성에 대한 새로운 값이 있습니다. @ grapecity / wijmo.grid.immutable 모듈의 copyObject 함수를 사용하여 객체를 복제합니다. 브라우저에서 구현한 경우, Object.assign 함수를 효과적으로 사용하고 그렇지 않은 경우, (예 : IE) 사용자 정의 구현으로 대체합니다.


REMOVE_ITEM 및 CHANGE_ITEM 작업을 처리하려면 이 변경의 영향을 받는 items 배열의 기존 항목 및 해당 인덱스를 알아야 합니다 이 샘플에서는 가장 간단하고 빠른 방법을 사용합니다. 항목의 인덱스는 액션 데이터의 인덱스 속성으로 전달됩니다. (ImmutabilityProvider.dataChanged 이벤트는 이 정보를 제공합니다)


어떤 이유로 인해 이 방법이 효과가 없다면 action 데이터에서 변경하려는 원래 항목을 전달할 수도 있습니다. items.indexOf () 메소드를 사용하여 색인을 찾거나 항목 id 로 검색합니다.


CHANGE_ITEM 작업의 경우 변경하려는 기존 항목뿐만 아니라 항목의 새 속성 값도 알아야 합니다. ImmutabilityProvider.dataChanged 이벤트의 데이터는 새 항목 속성 값을 포함하는 복제 개체를 제공함으로써 이러한 정보도 제공합니다. 이 복제된 객체는 action의 항목 속성으로 전달되며, reducer가 새 속성값으로 새로 복제된 항목을 작성하고 이전 항목 대신 복제된 항목 배열에서 사용하기 위해 사용됩니다 .


복제된 항목 배열에 추가된 복제된 항목의 경우 의도치 않은 돌연변이로부터 항목을 보호하기 위해 Object.freeze 를 호출합니다.


View 컴포넌트 - 프레젠테이션 및 컨테이너


샘플의 UI는 GridView.jsx 파일의 단일 GridView 프리젠테이션  컴포넌트에서 구현됩니다. 그리고 Redux 의 React 바인딩 에서 관습적으로 GridViewContainer.jsx 파일에 구현된 컨테이너 컴포넌트 - GridViewContainer 와 함께 사용합니다. GridViewContainer는 GridViewContainer.jsx의 wrapper일 뿐이며, 프리젠테이션 GridView에 Redux Store의 필요한 데이터를 제공하기 위한 것 입니다.


데이터는 데이터그리드에 표현된 items 배열과 action creator 함수 (addItemAction , removeItemAction 등)입니다. this.props 객체를 통해 GridView 에서 props 로 사용할 수 있습니다.


GridViewContainer를 구현하는 방법은 다음과 같습니다.


import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { GridView } from './GridView';
import { addItemAction, removeItemAction, changeItemAction, changeCountAction } from './actions';


const mapStateToProps = state => ({
    items: state.items,
    itemCount: state.itemCount
})
const mapDispatchToProps = dispatch => {
    return bindActionCreators(
        { 
            addItemAction, removeItemAction, changeItemAction, changeCountAction 
        }, 
        dispatch
    );
};

export const GridViewContainer = connect(
    mapStateToProps,
    mapDispatchToProps
  )(GridView); 


GridView presentational 컴포넌트는 컴포넌트의 render 메소드에 있는 다음의 코드를 사용하여 관련된 ImmutabilityProvider와 함께 FlexGrid 컴포넌트를 추가합니다. 


import * as wjFlexGrid from '@grapecity/wijmo.react.grid';
import * as wjGridFilter from '@grapecity/wijmo.react.grid.filter';
import { DataChangeEventArgs, DataChangeAction } from '@grapecity/wijmo.grid.immutable';
import { ImmutabilityProvider } from '@grapecity/wijmo.react.grid.immutable';
....


<wjFlexGrid.FlexGrid
        allowAddNew 
        allowDelete
        initialized={this.onGridInitialized}>
    <ImmutabilityProvider 
        itemsSource={this.props.items}
        dataChanged={this.onGridDataChanged} />
    <wjGridFilter.FlexGridFilter/>
    <wjFlexGrid.FlexGridColumn binding="id" header="ID" width={80} isReadOnly={true}></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="start" header="Date" format="d"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="end" header="Time" format="t"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="country" header="Country"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="product" header="Product"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="sales" header="Sales" format="n2"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="downloads" header="Downloads" format="n0"></wjFlexGrid.FlexGridColumn>
    <wjFlexGrid.FlexGridColumn binding="active" header="Active" width={80}></wjFlexGrid.FlexGridColumn>
</wjFlexGrid.FlexGrid>


ImmutabilityProvider는 자체적으로 this.props.items 속성에 바인딩되어 있는 itemsSource 속성을 포함하고 있으며, 이 속성은 전역 애플리케이션 상태에서 items 배열을 포함하고 있습니다.  Store reducer가 사용자 변경사항을 적용하기 위해 새로운 배열 복제본을 생성할 때마다 this.props.items 가 새 배열 인스턴스로 자동 업데이트되며 ImmutabilityProvider는 FlexGrid가 해당 내용을 업데이트하여 변경 사항을 반영하도록 합니다.



ImmutabilityProvider의 dataChanged 이벤트는 사용자가 DataGrid에서 데이터를 변경하고 변경할 때마다 호출됩니다. onGridDataChanged 핸들러 함수에 바인딩되어 있으며 다음과 같이 구현됩니다.


onGridDataChanged(s: ImmutabilityProvider, e: DataChangeEventArgs) {
    switch (e.action) {
        case DataChangeAction.Add:
            this.props.addItemAction(e.newItem);
            break;
        case DataChangeAction.Remove:
            this.props.removeItemAction(e.oldItem, e.itemIndex);
            break;
        case DataChangeAction.Change:
            this.props.changeItemAction(e.newItem, e.itemIndex);
            break;
        default:
            throw 'Unknown data action'
    }
}


핸들러는 적절한 action creator 함수를 호출하며, action creator 함수는 GridViewContainer 컨테이너 컴포넌트 덕분에 this.props 객체를 통해 GridView 컴포넌트에서도 사용할 수 있습니다. action 데이터는 DataChangeEventArgs 타입의 이벤트 인수에서 검색됩니다수행된 변경 작업에 대한 정보(작업 속성, Add, Remove 또는 Change 값), 소스 배열의 영향을 받는 항목에 대한 인덱스(index) 및 영향을 받는 항목에 대한 참조(데이터 작업에 따라 oldItem 또는 newItem)가 제공됩니다.


여기서 특별한 경우는 oldItem 및 newItem 속성이 모두 사용되는 Change 작업입니다. oldItem에는 속성 값이 변경되어야 하는 원래 항목이 포함되고 newItem에는 새 속성 값이 있는 복제본이 포함됩니다.


따라서 소스 배열을 직접 변경하는 대신, ImmutabilityProvider가 연결된 FlexGrid는 dataChanged 이벤트를 발생시키며, 이 이벤트는 이벤트에서 제공한 데이터를 사용하여 적절한 action creator 함수를 호출합니다 . 이 호출은 action을 Redux Store에 전달한 후 Store의 reducer에 전달 합니다.


reducer는 데이터에 적용된 변경 사항들을 가진 배열의 복제본을 생성하고, 이 새로운 배열 복제본은 ImmutabilityProvider.itemsSource에 바인딩 되어 있는 this.props.items에서 사용 가능하게 됩니다.  ImmutabilityProvider는 이 새로운 배열 인스턴스를 감지하여 FlexGrid의 컨텐츠를 새로고침합니다.


View에는 사용자가 DataGrid에 표시되는 배열의 크기를 변경할 수 있는 Menu 컴포넌트가 포함되어 있습니다. 값을 변경하면 Redux Store는 지정된 길이의 새 items 배열을 만듭니다컴포넌트의 render 메소드에서 이 코드를 사용하여 메뉴가 view에 추가됩니다.


import * as wjInput from '@grapecity/wijmo.react.input';
....


<wjInput.Menu header='Items number'
    value={this.props.itemCount}
    itemClicked={this.onCountChanged}>
    <wjInput.MenuItem value={5}>5</wjInput.MenuItem>
    <wjInput.MenuItem value={50}>50</wjInput.MenuItem>
    <wjInput.MenuItem value={100}>100</wjInput.MenuItem>
    <wjInput.MenuItem value={500}>500</wjInput.MenuItem>
    <wjInput.MenuItem value={5000}>5,000</wjInput.MenuItem>
    <wjInput.MenuItem value={10000}>10,000</wjInput.MenuItem>
    <wjInput.MenuItem value={50000}>50,000</wjInput.MenuItem>
    <wjInput.MenuItem value={100000}>100,000</wjInput.MenuItem>
</wjInput.Menu>


메뉴의 value 속성은 현재 items 배열 길이를 포함하는 전역 Redux 상태의 itemCount 속성에 바인딩됩니다 사용자가 메뉴 드롭 다운 목록에서 다른 값을 선택하면 itemClicked 이벤트가 트리거되고 다음과 같은 간단한 onCountChanged 이벤트 핸들러 함수를 호출합니다.


onCountChanged(s: wjcInput.Menu) {
    this.props.changeCountAction(s.selectedValue);
}


핸들러는 changeCountAction action creator 함수를 호출하여 새로운 배열 길이를 action 데이터로 전달합니다. 이를 통해 Store reducer가 지정된 길이의 새 items 배열을 생성합니다. View의 다른 UI 요소는 읽기 전용 DataGrid이며 items 배열의 내용만 표시합니다.


데이터 그리드에는 "Show Data" 확인란이 있으며,이를 통해 사용자는 데이터 배열에서 DataGrid를 일시적으로 연결 해제 할 수 있습니다. 다음은 이러한 컴포넌트를 추가하는 render 메소드에서의 JSX입니다.


<input type="checkbox" 
    checked={this.state.showStoreData}
    onChange={ (e) => { 
        this.setState({ showStoreData: e.target.checked}); 
} } /> 
<b>Show data</b>
<wjFlexGrid.FlexGrid 
    itemsSource={this.state.showStoreData ? this.props.items : null} 
    isReadOnly/> 
</div>


"Show Data" 체크 박스는 controlled component이며, 컴포넌트 상태의 showStoreData 속성에 해당 값을 저장합니다. 여기에서는 로컬 컴포넌트 상태를 사용하여 이 값을 저장합니다. 이 속성은 특정 속성에 대한 view이므로 나머지 애플리케이션에는 적합하지 않습니다. 그러나 모든 것을 Redux 상태로 저장하는 것을 선호한다면 아무런 문제없이 쉽게 이동할 수 있습니다. FlexGrid.itemsSource의 속성이 showStoreData에 따라 Store의 items 배열 또는 null 값에 바인딩 된다는 것을 참고하시길 바랍니다.


애플리케이션 실행하기


애플리케이션의 진입점은 app.jsx 파일입니다. 여기서 모든 애플리케이션 조각을 모아 루트 애플리케이션 컴포넌트를 실행합니다.


import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
//Application
import { appReducer } from './reducers';
import { GridViewContainer } from './GridViewContainer';

// Create global Redux Store
const store = createStore(appReducer);

class App extends React.Component<any, any> {
    render() {
        return <Provider store={store}>
            <GridViewContainer />
          </Provider>;
    }
}

ReactDOM.render(<App />, document.getElementById('app'));


우리는 애플리케이션 store를 만들어 reducer로 전달합니다. 그리고 우리는 GridViewContainer 컨테이너 컴포넌트를 렌더링하고 GridView presentational 컴포넌트를 렌더링하여 전역 Store 데이터를 props로 전달합니다. 우리는 애플리케이션 컴포넌트 트리를 react-redux Provider 컴포넌트로 Wrap하여 모든 애플리케이션 컴포넌트에서 Store에 쉽게 액세스 할 수 있도록 합니다.


결론


관련 ImmutabilityProvider 컴포넌트와 함께 FlexGrid DataGrid를 사용하면 데이터 불변성에 대한 Redux 요구 사항을 손상시키지 않고 애플리케이션 UI에서 편집 가능한 DataGrid를 사용할 수 있습니다. 이 솔루션은 매우 큰 데이터에서도 우수한 성능을 보여줍니다.






 
  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.