Skip to content

Commit

Permalink
Grid react to functional (#2702)
Browse files Browse the repository at this point in the history
* Update configs to work with react hooks

* dxGrid: convert react from class to func

* lint fixes

* wrap callbacks in use callback and some refactor

* demo review changes

* remove named imports from react

* fix test

---------

Co-authored-by: Eldar Iusupzhanov <ferrarijed@gmail.com>
  • Loading branch information
ivanblinov2k17 and Tucchhaa authored Jul 31, 2023
1 parent d707eed commit 5d87f4f
Show file tree
Hide file tree
Showing 96 changed files with 4,037 additions and 4,797 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
'spellcheck',
'no-only-tests',
'deprecation',
'react-hooks',
],
rules: {
'spellcheck/spell-checker': (() => {
Expand Down Expand Up @@ -283,6 +284,8 @@ module.exports = {
'prefer-destructuring': 0,
'no-param-reassign': ['error', { 'props': false }],
'no-only-tests/no-only-tests': 'error',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
extends: [
'eslint:recommended',
Expand Down Expand Up @@ -455,7 +458,7 @@ module.exports = {
],
quotes: ['error', 'single', { avoidEscape: true }],
'prefer-template': 'error',
'func-style': ['error', 'declaration'],
'func-style': ['error', 'declaration', { 'allowArrowFunctions': true }],
'react/jsx-curly-brace-presence': [
'error',
{
Expand Down
40 changes: 18 additions & 22 deletions JSDemos/Demos/DataGrid/AdvancedMasterDetailView/React/AddressTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,24 @@ import { Form, Item } from 'devextreme-react/form';

const items = ['Address', 'City', 'Region', 'PostalCode', 'Country', 'Phone'];

class AddressTab extends React.Component {
render() {
return (
<Form
formData={this.props.data}
colCount={2}
className="address-form form-container"
>
{
items.map((item, index) => <Item
dataField={item}
key={index}
render={this.renderFormItem}
/>)
}
</Form>
);
}
const renderFormItem = (item) => (
<span>{item.editorOptions.value}</span>
);

renderFormItem(item) {
return <span>{item.editorOptions.value}</span>;
}
}
const AddressTab = (props) => (
<Form
formData={props.data}
colCount={2}
className="address-form form-container"
>
{
items.map((item, index) => <Item
dataField={item}
key={index}
render={renderFormItem}
/>)
}
</Form>
);

export default AddressTab;
42 changes: 19 additions & 23 deletions JSDemos/Demos/DataGrid/AdvancedMasterDetailView/React/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,25 @@ const suppliersData = createStore({
loadUrl: `${url}/GetSuppliers`,
});

class App extends React.Component {
render() {
return (
<DataGrid
dataSource={suppliersData}
remoteOperations={true}
showBorders={true}
id="gridContainer"
>
<MasterDetail
enabled={true}
component={MasterDetailView}
/>
<Paging defaultPageSize={15} />
const App = () => (
<DataGrid
dataSource={suppliersData}
remoteOperations={true}
showBorders={true}
id="gridContainer"
>
<MasterDetail
enabled={true}
component={MasterDetailView}
/>
<Paging defaultPageSize={15} />

<Column dataField="ContactName" />
<Column dataField="ContactTitle" />
<Column dataField="CompanyName" />
<Column dataField="City" />
<Column dataField="Country" />
</DataGrid>
);
}
}
<Column dataField="ContactName" />
<Column dataField="ContactTitle" />
<Column dataField="CompanyName" />
<Column dataField="City" />
<Column dataField="Country" />
</DataGrid>
);

export default App;
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,21 @@ import { TabPanel, Item } from 'devextreme-react/tab-panel';
import AddressTab from './AddressTab.js';
import OrdersTab from './OrdersTab.js';

class MasterDetailView extends React.Component {
constructor(props) {
super(props);
this.renderOrdersTab = this.renderOrdersTab.bind(this);
this.renderAddressTab = this.renderAddressTab.bind(this);
}
const MasterDetailView = (props) => {
const renderOrdersTab = React.useCallback(() => (
<OrdersTab supplierId={props.data.key} />
), [props.data.key]);

render() {
return (
<TabPanel>
<Item title="Orders" render={this.renderOrdersTab} />
<Item title="Address" render={this.renderAddressTab} />
</TabPanel>
);
}
const renderAddressTab = React.useCallback(() => (
<AddressTab data={props.data.data} />
), [props.data.data]);

renderOrdersTab() {
return <OrdersTab supplierId={this.props.data.key} />;
}

renderAddressTab() {
return <AddressTab data={this.props.data.data} />;
}
}
return (
<TabPanel>
<Item title="Orders" render={renderOrdersTab} />
<Item title="Address" render={renderAddressTab} />
</TabPanel>
);
};

export default MasterDetailView;
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,44 @@ import { createStore } from 'devextreme-aspnet-data-nojquery';

const url = 'https://js.devexpress.com/Demos/Mvc/api/DataGridAdvancedMasterDetailView';

class OrderHistory extends React.Component {
constructor(props) {
super(props);
this.state = {
orderHistoryStore: null,
};
}

render() {
return (
<DataGrid
dataSource={this.state.orderHistoryStore}
showBorders={true}
>
<Paging defaultPageSize={5} />

<Column dataField="OrderID" />
<Column dataField="OrderDate" dataType="date" />
<Column dataField="ShipCountry" />
<Column dataField="ShipCity" />
<Column dataField="UnitPrice" format="currency" />
<Column dataField="Quantity" />
<Column dataField="Discount" format="percent" />

<Summary>
<TotalItem column="UnitPrice" summaryType="sum">
<ValueFormat format="currency" precision={2} />
</TotalItem>
<TotalItem column="Quantity" summaryType="count" />
</Summary>

</DataGrid>
);
}

componentDidUpdate(prevProps) {
const { productId } = this.props;
if (prevProps.productId !== productId) {
this.setState({
orderHistoryStore: createStore({
key: 'OrderID',
loadParams: { ProductID: productId },
loadUrl: `${url}/GetOrdersByProduct`,
}),
const OrderHistory = ({ productId }) => {
const [orderHistoryStore, setOrderHistoryStore] = React.useState(null);

React.useEffect(() => {
if (productId) {
const newOrderHistoryStore = createStore({
key: 'OrderID',
loadParams: { ProductID: productId },
loadUrl: `${url}/GetOrdersByProduct`,
});
setOrderHistoryStore(newOrderHistoryStore);
}
}
}
}, [productId]);

return (
<DataGrid
dataSource={orderHistoryStore}
showBorders={true}
>
<Paging defaultPageSize={5} />

<Column dataField="OrderID" />
<Column dataField="OrderDate" dataType="date" />
<Column dataField="ShipCountry" />
<Column dataField="ShipCity" />
<Column dataField="UnitPrice" format="currency" />
<Column dataField="Quantity" />
<Column dataField="Discount" format="percent" />

<Summary>
<TotalItem column="UnitPrice" summaryType="sum">
<ValueFormat format="currency" precision={2} />
</TotalItem>
<TotalItem column="Quantity" summaryType="count" />
</Summary>

</DataGrid>
);
};

export default OrderHistory;
66 changes: 25 additions & 41 deletions JSDemos/Demos/DataGrid/AdvancedMasterDetailView/React/OrdersTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,33 @@ import { Form, Item, Label } from 'devextreme-react/form';
import ProductSelectBox from './ProductSelectBox.js';
import OrderHistory from './OrderHistory.js';

class OrdersTab extends React.Component {
constructor(props) {
super(props);
this.state = {
chosenProductId: null,
};
this.productChanged = this.productChanged.bind(this);
this.renderSelectBox = this.renderSelectBox.bind(this);
this.renderOrderHistory = this.renderOrderHistory.bind(this);
}
const OrdersTab = (props) => {
const [chosenProductId, setChosenProductId] = React.useState(null);

render() {
return (
<Form
labelLocation="top"
className="form-container"
>
<Item render={this.renderSelectBox}>
<Label text="Product" />
</Item>
<Item render={this.renderOrderHistory}>
<Label text="Order History" />
</Item>
</Form>
);
}
const renderSelectBox = React.useCallback(() => (
<ProductSelectBox
supplierId={props.supplierId}
productId={chosenProductId}
onProductChanged={setChosenProductId} />
), [chosenProductId, props.supplierId]);

renderSelectBox() {
return <ProductSelectBox
supplierId={this.props.supplierId}
productId={this.state.chosenProductId}
onProductChanged={this.productChanged} />;
}
const renderOrderHistory = React.useCallback(() => (
<OrderHistory productId={chosenProductId} />
), [chosenProductId]);

renderOrderHistory() {
return <OrderHistory productId={this.state.chosenProductId} />;
}

productChanged(productId) {
this.setState({
chosenProductId: productId,
});
}
}
return (
<Form
labelLocation="top"
className="form-container"
>
<Item render={renderSelectBox}>
<Label text="Product" />
</Item>
<Item render={renderOrderHistory}>
<Label text="Order History" />
</Item>
</Form>
);
};

export default OrdersTab;
Loading

0 comments on commit 5d87f4f

Please sign in to comment.