devextreme-react v23.2.5
DevExtreme React UI and Visualization Components
This project allows you to use DevExtreme Widgets as React Components.
- Getting started
- API Reference
- State Management
- Markup Customization
- DevExtreme Validation
- Working With Data
- Typescript Support
- License
- Support & feedback
Getting Started
You can try this live example (no need to install anything).
If you’d rather use a local development environment check out the sections below.
Prerequisites
Node.js and npm are required
Install DevExtreme
Install the devextreme and devextreme-react npm packages:
npm install --save devextreme@18.1 devextreme-react
Additional Configuration
The further configuration steps depend on which build tool, bundler or module loader you are using. Please choose the one you need:
Use DevExtreme Components
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
ReactDOM.render(
<Button text='Example Button' />,
document.getElementById('root')
);
Note that DevExtreme styles are required.
API Reference
The complete list of components and their APIs are described in the DevExtreme API Reference.
See Markup Customization for details on how to implement and apply templates.
State Management
DevExtreme React components support both Controlled and Uncontrolled state modes.
Controlled Mode
In the controlled mode, a parent component passes a component's state using its props. This mode provides the following capabilities:
- Control component state externally (stateless behavior)
- Share state between components in your app
- Persist and restore state
To control a component's state, provide the value for the required property and handle the event that is fired when it is changed (use the appropriate property with the on
prefix):
import React from 'react';
import ReactDOM from 'react-dom';
import { TextBox } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 'TEXT'
};
this.handleChange = this.handleChange.bind(this);
}
render() {
return (
<div>
<TextBox
value={this.state.text}
onValueChanged={this.handleChange}
valueChangeEvent='input'
/>
<br />
<div>{this.state.text}</div>
</div>
);
}
handleChange(e) {
this.setState({
text: e.value.toUpperCase().replace('A','_')
});
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
Uncontrolled Mode
Sometimes there is no need to handle all the component's updates, thus DevExtreme components can manage their state internally which reduces the amount of code required.
Note that if you want to specify an initial value for an option in the uncontrolled mode, you should use an appropriate property with the default
prefix. In the example below, the currentView
option's initial value is defined using the defaultCurrentView
property.
import React from 'react';
import ReactDOM from 'react-dom';
import { Scheduler } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
const appointments = [
{
text: 'Website Re-Design Plan',
startDate: new Date(2017, 4, 22, 9, 30),
endDate: new Date(2017, 4, 22, 11, 30)
}, {
text: 'Book Flights to San Fran for Sales Trip',
startDate: new Date(2017, 4, 22, 12, 0),
endDate: new Date(2017, 4, 22, 13, 0),
allDay: true
}, {
text: 'Install New Router in Dev Room',
startDate: new Date(2017, 4, 23, 10, 30),
endDate: new Date(2017, 4, 23, 16, 30)
}
];
ReactDOM.render(
<Scheduler
dataSource={appointments}
height={600}
editing={false}
defaultCurrentView={'week'}
defaultCurrentDate={new Date(2017, 4, 22)}
startDayHour={9}
/>,
document.getElementById('root')
);
Getting Widget Instance
In some cases, a widget instance is required when you need to call a widget method. You can get it by assigning a callback function to the component's ref
property. This function accepts the mounted DevExtreme Component as an argument whose instance
property stores the widget instance.
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, TextBox } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
class Example extends React.Component {
render() {
return (
<div>
<TextBox ref={(ref) => this.textBox = ref.instance}/>
<Button text='Go to the TextBox' onClick={() => this.textBox.focus()} />
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
Markup Customization
You can customize widget elements' appearance via the corresponding template properties. In the DevExtreme API, the corresponding options have the Template
suffix (e.g. dxList's itemTemplate option).
To specify a DevExtreme React Component template, use the Render
or Component
suffix instead.
If a widget has an option called template
(e.g. Button's template option) the corresponding React Component properties are called render
and component
.
Use a property with the Render
suffix to specify a rendering function:
import React from 'react';
import ReactDOM from 'react-dom';
import { List } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
const items = [
{ text: '123' },
{ text: '234' },
{ text: '567' }
];
ReactDOM.render(
<List items={items} itemRender={(item) => <i>Function template for item <b>{item.text}</b></i>}/>,
document.getElementById('root')
);
Functional Components can cause unnecessary render calls. In such cases, consider using the PureComponent or the shouldComponentUpdate method.
A template component can be specified using a property with the Component
suffix:
import React from 'react';
import ReactDOM from 'react-dom';
import { List } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
const items = [
{ text: '123' },
{ text: '234' },
{ text: '567' }
];
class Item extends React.PureComponent {
render() {
return (
<i onClick={this.handleClick}>
Component template for item {this.props.text}.
</i>
);
}
}
ReactDOM.render(
<List items={items} itemComponent={Item} />,
document.getElementById('root')
);
Note: You cannot use the key
prop in template components because it is a special React prop. Use dxkey
instead.
Use the render
property to specify a rendering function for a widget with template
option:
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
class CounterButton extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0
};
this.handleClick = this.handleClick.bind(this);
}
render() {
return (
<Button
text={this.props.text}
render={(btn) => <div style={{ padding: 20 }}>{btn.text} (<b>{this.state.counter}</b>)</div>}
onClick={this.handleClick}
/>
);
}
handleClick() {
this.setState({
counter: this.state.counter + 1
});
}
}
ReactDOM.render(
<CounterButton text='Click me!' />,
document.getElementById('root')
);
The components that displays content in an overlaying window (for example, ScrollView), allow to specify the content as component children:
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, ScrollView } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
class Example extends React.Component {
render() {
return (
<ScrollView height={200} width={200}>
<Button text='Show alert' onClick={() => alert('shown')} />
<br />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sed lacus
egestas, facilisis urna nec, fringilla nibh. Maecenas enim felis, ultricies
pretium aliquet ut, aliquam id urna. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Nam viverra est at neque fringilla, non iaculis magna
ultrices. Nunc posuere tincidunt elit a molestie. Nulla aliquet metus ex. Nunc
aliquam volutpat libero, ac tincidunt felis consectetur id. Sed diam lectus,
dictum non tempus fringilla, semper in dui. Donec at hendrerit massa. Aenean
quis suscipit nisi. Cras sed eros tristique, venenatis diam in, rhoncus enim.
</p>
<p>
Orci varius natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Curabitur et ex sit amet odio efficitur fermentum.
Donec lobortis hendrerit massa. Praesent tempus cursus tempus. Maecenas at
dolor lacus. Vestibulum suscipit ac mi vitae posuere. Maecenas id urna eget
sapien volutpat laoreet. Sed nulla purus, aliquam nec augue vel, consequat
tincidunt erat. Phasellus hendrerit rhoncus erat, ut fermentum orci molestie a.
</p>
</ScrollView>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
DevExtreme Validation
DevExtreme React editors support built-in data validation.
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, TextBox, ValidationGroup, ValidationSummary, Validator } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
class Example extends React.Component {
validationRules = {
email: [
{ type: 'required', message: 'Email is required.' },
{ type: 'email', message: 'Email is invalid.' }
],
password: [
{ type: 'required', message: 'Password is required.' }
]
};
constructor(props) {
super(props);
this.validate = this.validate.bind(this);
}
render() {
return (
<ValidationGroup>
<TextBox defaultValue={'email@mail.com'}>
<Validator validationRules={this.validationRules.email} />
</TextBox>
<TextBox defaultValue={'password'}>
<Validator validationRules={this.validationRules.password} />
</TextBox>
<ValidationSummary />
<Button
text={'Submit'}
onClick={this.validate}
/>
</ValidationGroup>
);
}
validate(params) {
const result = params.validationGroup.validate();
if (result.isValid) {
// form data is valid
//params.validationGroup.reset();
}
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
Working with Data
DevExtreme includes the data layer that enables you to read and write data stored in different data sources.
The example below demonstrates how to use a DataSource with DevExtreme Components.
import React from 'react';
import ReactDOM from 'react-dom';
import DataSource from 'devextreme/data/data_source';
import { List } from 'devextreme-react';
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.compact.css';
const items = [
{ text: '123' },
{ text: '234' },
{ text: '567' }
];
class Example extends React.Component {
constructor(props) {
super(props);
this.dataSource = new DataSource({
store: {
type: 'array',
data: items
},
sort: [
{ getter: 'text', desc: true }
],
pageSize: 1
});
}
render() {
return (
<List dataSource={this.dataSource} />
);
}
componentWillUnmount() {
this.dataSource.dispose();
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
Note that a DataSource is considered as a 'service'. So, modifying its properties does not cause component rerendering.
Typescript Support
We provide TypeScript declarations for DevExtreme Components. Strict typing allows you to catch many bugs and improve your workflow by adding features like auto-completion and automated refactoring.
Below is an example of appearance customization using TypeScript:
import * as React from "react";
import * as ReactDOM from "react-dom";
import { List } from "devextreme-react";
import "devextreme/dist/css/dx.common.css";
import "devextreme/dist/css/dx.light.compact.css";
interface IListItemProps {
text: string;
}
class Item extends React.Component<IListItemProps, { counter: number }> {
constructor(props: IListItemProps) {
super(props);
this.state = {
counter: 0
};
this.handleClick = this.handleClick.bind(this);
}
public render() {
return (
<i onClick={this.handleClick}>
Component template for item {this.props.text}. <b>Clicks: {this.state.counter}</b>
</i>
);
}
private handleClick() {
this.setState({
counter: this.state.counter + 1
});
}
}
const items: IListItemProps[] = [
{ text: "123" },
{ text: "234" },
{ text: "567" }
];
ReactDOM.render(
<List items={items} itemComponent={Item} />,
document.getElementById("root")
);
License
DevExtreme React components are released as an MIT-licensed (free and open-source) add-on to DevExtreme.
Familiarize yourself with the DevExtreme License.
Support & Feedback
- For general React questions, check React Docs
- For questions regarding DevExtreme libraries and widgets' APIs, use DevExpress Support Center
8 days ago
8 days ago
15 days ago
15 days ago
22 days ago
22 days ago
28 days ago
29 days ago
1 month ago
1 month ago
1 month ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
7 months ago
6 months ago
9 months ago
9 months ago
8 months ago
7 months ago
8 months ago
8 months ago
8 months ago
6 months ago
9 months ago
6 months ago
8 months ago
9 months ago
7 months ago
9 months ago
6 months ago
6 months ago
8 months ago
6 months ago
7 months ago
10 months ago
5 months ago
7 months ago
9 months ago
5 months ago
5 months ago
10 months ago
7 months ago
7 months ago
8 months ago
8 months ago
10 months ago
7 months ago
8 months ago
9 months ago
8 months ago
8 months ago
9 months ago
6 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
11 months ago
11 months ago
11 months ago
12 months ago
1 year ago
1 year ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago