Last active
April 12, 2019 09:32
-
-
Save DTupalov/e688a9cb640b91af52ce4bafb776366a to your computer and use it in GitHub Desktop.
`customCell` варианты использования
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* https://github.com/DTupalov/react-material-ui-datatable#reactmuidatatables-api | |
* | |
* Предполагается, что Datatable является uncontrolled component. | |
* Для выделения этого аспекта, принято пропы для таких компонентов именовать с приставкой `default`. | |
* Подробнее почитать тут: https://reactjs.org/docs/uncontrolled-components.html#default-values | |
* | |
* Необходимо понять, каким образом для `defaultColumns` использовать метод `customCell`, | |
* который может возвращать значение в зависимости от состояния родителя. | |
* Вопрос состоит в том, "можно ли" и "правильно ли" реализовать частично контролируемые и неконтролируемые значения. | |
* Для себя выявил, что React считает неконтролируемым только сериализуемые данные (которые можно хранить в state), | |
* в то время как функции вызываются те, которые передаются в момент рендера в компонент. | |
* Это можно проверить на классическом примере с <input defaultValue="" onChange={(e) => {}}/>, где `onChange` можно подменять | |
* при каждом ререндере, и он будет применяться к новому значению, | |
* в то время как defaultValue применяется только при инициализации компонента input. | |
* | |
* Абстрактный пример | |
*/ | |
class MyPage extends React.Component { | |
state = { | |
loading: false, | |
data: null, | |
} | |
onDeleteEntities = async (selectedEntities) => { | |
this.setState({loading: true}); | |
await axios.delete(`./api/entity`, {selectedEntities})); | |
this.setState({loading: false}); | |
} | |
render() { | |
const columns = const columns = [{ | |
name: 'a', | |
label: 'A', | |
// Кастомная ячейка, где значение - это кнопка. При выполнении запроса, кнопка должна быть неактивной, | |
// т.е. она зависит от родительского стейта loading | |
customCell: (value) => { | |
return <button onClick={/*move to edit page*/} disabled={this.state.loading}>{value}</button> | |
} | |
}] | |
return <Datatable | |
defaultData={data} | |
defaultColumns={columns} | |
// Панель, которая появляется при выборе элементов таблицы. | |
toolbarSelectActions={ | |
(selectedEntities) => { | |
return <DeleteButton disabled={this.state.loading} onClick={() => this.onDeleteEntities(selectedEntities)}/> | |
} | |
} | |
/> | |
} | |
} | |
/** | |
* Вариант 1 | |
* Спрятать внутри компонента логику разделения columns data (name, label etc) и columns methods (customCell, customSort etc), | |
* где data будет использоваться только при инициализации, а methods переданные в момент рендера. | |
* | |
* Плюсы: | |
* - Удобная запись с точки зрения публичного API, где видно что задекларировано в описании к колонке (данные и методы) | |
* | |
* Минусы: | |
* - Возможно, неочевидное поведение, когда задекларировано, что все что внутри defaultColumns | |
* будет использовано при инициализации, а на самом деле - нет | |
*/ | |
/** | |
* Вариант 2 | |
* Разделить на уровне API декларацию данных для колонки defaultColumns и customColumnsMethods | |
* | |
* Плюсы: | |
* - По описанию очевидно что используется только при инициализации, а что - при каждом рендере. | |
* | |
* Минусы: | |
* - Возможно, запись будет неудобной для чтения и полноценного понимания что происходит в конкретной колонке/ячейке | |
*/ | |
/** | |
* Вариант 3 | |
* Вынести рендер-функцию `customCell` вообще как отдельный prop с сигнатурой `(cellValue, column, row) => string | React.Component` | |
* | |
* Плюсы: | |
* - Это обычная рендер-функция, которая вызывается при каждом рендере (as controlled) | |
* | |
* Минусы: | |
* - Получается недекларативное описание ячейки в колонке. | |
* - Есть нюансы. Если захочется сделать две колонки с одинанаковым путем, в таком случае непонятно, каким образом это различать в `customCell` | |
*/ | |
/** | |
* Вариант 4 | |
* ??? | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment