React Development: Web Document Management App
Tags: react, webdev, javascript
Published: 2021-06-07 05:35:56

[Dynamic Web TWAIN](https://www.dynamsoft.com/web-twain/overview/) is a JavaScript library designed for document scanning and document management. This tutorial guides through React development. You will see how to combine Reactjs and Dynamic Web TWAIN to build a simple web application which can acquire images from a document scanner and load images from local hard drive.

![React web document scanning](https://www.dynamsoft.com/codepool/img/2021/06/react-web-document-scanning.PNG)

## What You Should Know About Dynamic Web TWAIN
- [![](https://img.shields.io/badge/Download-Offline%20SDK-orange)](https://www.dynamsoft.com/web-twain/downloads)
- [![](https://img.shields.io/badge/Get-30--day%20FREE%20Trial%20License-blue)](https://www.dynamsoft.com/customer/license/trialLicense/?product=dwt)

## Making Web Document Management App Using React
In the following paragraphs, we will create the skeleton of a React project first and then integrate Dynamic Web TWAIN into the project to implement document scanning and management.

### Getting Started with a New React Project

To create a new React project, you can choose one of the following ways:

**npm**

```bash
npm install -g create-react-app
create-react-app document-scan
```

**npx**

```bash
npx create-react-app document-scan
```

**Yarn**

```bash
yarn create react-app document-scan
```

### Implementing Document Scanning with Dynamic Web TWAIN SDK
Install dependent packages via npm command:

```bash
npm install dwt@17.0.2
npm install @babel/core @babel/preset-env
npm i ncp -g
```

Dynamic Web TWAIN SDK consists of platform-specific service applications (for scanner communication) and JavaScript library files, which are located in the `node_modules/dwt/dist` folder for programming and distribution. We use `ncp` to copy resources to the `public` folder of the React project:

```bash
ncp node_modules/dwt/dist public/dwt-resources
```

The next step is to create a React component in `DynamsoftSDK.js`:

```js
import React from 'react';
import Dynamsoft from 'dwt';

export default class DWT extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            scanners: [],
            currentScanner: "Looking for devices.."
        };
        this.DWObject = null;
        this.containerId = 'dwtcontrolContainer';
        this.width = "100%";
        this.height = "600";
    }

    componentDidMount() {

    }

    render() {
        return (
           
        );
    }
}

```

In `componentDidMount()`, we set the resource path for initializing the Dynamic Web TWAIN object. As the `OnWebTwainReady` event is trigged, we can get the information of connected document scanners and then update relevant UI elements:

```js
componentDidMount() {
    Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', () => {
        this.DWObject = Dynamsoft.DWT.GetWebTwain(this.containerId);
        if (this.DWObject) {
            let vCount = this.DWObject.SourceCount;
            let sourceNames = [];
            for (let i = 0; i < vCount; i++)
                sourceNames.push(this.DWObject.GetSourceNameItems(i));
            this.setState({ scanners: sourceNames });
        }
    });
    this.loadDWT();
}

loadDWT() {
    Dynamsoft.DWT.ProductKey = this.props.productKey;
    Dynamsoft.DWT.ResourcesPath = "dwt-resources";
    Dynamsoft.DWT.Containers = [{ ContainerId: this.containerId, Width: this.width, Height: this.height }];
    let checkScriptLoaded = () => {
        if (Dynamsoft.Lib.detect.scriptLoaded) {
            Dynamsoft.DWT.Load();
        } else {
            setTimeout(() => {
                checkScriptLoaded();
            }, 1000);
        }
    };
    checkScriptLoaded();
}
```

Because of lazy loading, checking SDK loading status is necessary.

Let's create the UI layout in `render()`:

```js
render() {
    return (
        <div style={{ width: "30%", margin: "0 auto" }}>
            <select style={{ width: "100%" }} tabIndex="1" value={this.state.currentScanner} onChange={(e) => this.onSourceChange(e.target.value)}>
                {
                    this.state.scanners.length > 0 ?
                        this.state.scanners.map((_name, _index) =>
                            <option value={_name} key={_index}>{_name}</option>
                        )
                        :
                        <option value="Looking for devices..">Looking for devices..</option>
                }
            </select>
            <button tabIndex="2" style={{ marginRight: "4%", width: "48%" }}
                onClick={() => this.acquireImage()}
                disabled={this.state.scanners.length > 0 ? "" : "disabled"}
            >Scan</button>
            <button tabIndex="3" style={{ margin: "2% 0", width: "48%" }}
                onClick={() => this.loadImagesOrPDFs()}
            >Load</button>
            <div id={this.containerId}></div>
        </div >
    );
}
```

There are two buttons, one for acquiring images from document scanners, and the other for loading images from local hard drive. The corresponding code implementation of button click event is as follows:

```js
acquireImage() {
    this.DWObject.CloseSource();
    for (let i = 0; i < this.DWObject.SourceCount; i++) {
        if (this.DWObject.GetSourceNameItems(i) === this.state.currentScanner) {
            this.DWObject.SelectSourceByIndex(i);
            break;
        }
    }
    this.DWObject.OpenSource();
    this.DWObject.AcquireImage();
}

loadImagesOrPDFs() {
    this.DWObject.IfShowFileDialog = true;
    this.DWObject.Addon.PDF.SetResolution(200);
    this.DWObject.Addon.PDF.SetConvertMode(1);
    this.DWObject.LoadImageEx("", 5,
        () => { },
        (errorCode, errorString) => alert(errorString));
}
```

Once the component is ready, we can add it to `App.js`:

```js
import logo from './logo.svg';
import DWTLogo from './icon-dwt.svg';
import DynamsoftLogo from './logo-dynamsoft-white-159X39.svg';
import './App.css';
import DWT from './DynamsoftSDK';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <a href="https://www.dynamsoft.com/Products/WebTWAIN_Overview.aspx" target="_blank" rel="noopener noreferrer" ><img src={DWTLogo} className="dwt-logo" alt="Dynamic Web TWAIN Logo" /></a>
        <div style={{ width: "10px" }}></div>
        <a href="https://reactjs.org/" target="_blank" rel="noopener noreferrer" ><img src={logo} className="App-logo" alt="logo" /></a>
        <div style={{ width: "18%" }}></div>
        <a href="https://www.dynamsoft.com" target="_blank" rel="noopener noreferrer" ><img src={DynamsoftLogo} className="ds-logo" alt="Dynamsoft Logo" /></a>
      </header>
      <main className="App-main">
        <DWT
          productKey="LICENSE-KEY"
        />
      </main>
    </div>
  );
}

export default App;
```

To make the SDK work successfully, you need to apply for a [30-day FREE trial license](https://www.dynamsoft.com/customer/license/trialLicense?product=dwt) and update the line:

```js
productKey="LICENSE-KEY"
```


Now, the simple web document management app is finished. We can run `npm start` to launch the app:

```bash
npm start
```

![React web document management](https://www.dynamsoft.com/codepool/img/2021/06/react-web-document-management.gif)

## Source Code

[https://github.com/dynamsoft-dwt/dwt-react-simple](https://github.com/dynamsoft-dwt/dwt-react-simple)