Mouser wheel actions can be detected using onWheel property. Here we will use deltaY property of onWheel event to find direction mouse wheel.

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Program

Observe below program. Whenever user scroll mouse wheel on image, detect scroll direction and increase or decrease width of image based on that

import React from 'react';
import classNames from 'classnames';

class ZoomImage extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      width:this.props.width
    };
    this.hadleMouseWheel = this.hadleMouseWheel.bind(this);
  }

  hadleMouseWheel(evt) {
    if(evt.deltaY > 0) {
        this.setState({
        width:(this.state.width - 5)
      });
    } else if(evt.deltaY < 0) {
      this.setState({
        width:(this.state.width + 5)
      });
    }
  }

  render() {
    const imgStyle = {
      width:this.state.width+'px'
    };
    const {width, ...props} = this.props;
    return (
      <img {...props} style={imgStyle} onWheel={this.hadleMouseWheel}/>
    );
  }
}

ZoomImage.propTypes = {
  width:React.PropTypes.number
}

ZoomImage.defaultProps = {
  width:400
}

export default ZoomImage;
Read More
We can control checking and unchecking of radio buttons and checkboxes using React state. Here we have to bind state variable to checked attribute of radio button or checkbox.

Program

Observe this code. Here we have bound the state variable checked to checked attribute of  radio button or checkbox.
import React from 'react';
import classNames from 'classnames';

class CheckAndUncheck extends React.Component {

  constructor(props) {
    super(props);
    this.checkIt = this.checkIt.bind(this);
    this.unCheckIt = this.unCheckIt.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      checked:false
    };
  }

  checkIt() {
    this.setState({
      checked:true
    });
  }

  unCheckIt() {
    this.setState({
      checked:false
    });
  }

  handleChange(evt) {
     if(this.state.checked !== evt.target.checked) {
        this.setState({
          checked:evt.target.checked
        });
     }
  }

  render() {
    return (
      <div>
        <div>
          <button onClick={this.checkIt}>Check</button> &nbsp;&nbsp;&nbsp; <button onClick={this.unCheckIt}>Uncheck</button>
        </div>
        <br/>
        <div>
          Checkbox :: <input type="checkbox" checked={this.state.checked} onChange={this.handleChange}/>
        </div>
        <br/>
        <div>
          Radio button :: <input type="radio" checked={this.state.checked} onChange={this.handleChange}/>
        </div>
      </div>
    );
  }
}

CheckAndUncheck.propTypes = {
}

CheckAndUncheck.defaultProps = {
}

export default CheckAndUncheck;
Read More
We can control scroll position of IFrame if the source of IFrame is from same domain. We can get reference of element using ref. Observe below program
Note : This program won't work for cross domains for security reasons. 

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Program

Observe below program. we can use contentWindow.scrollTo to scroll IFrame
import React from 'react';
import classNames from 'classnames';

class ScrollDetector extends React.Component {

  constructor(props) {
    super(props);
    this.scrollDown = this.scrollDown.bind(this);
    this.scrollUp = this.scrollUp.bind(this);
    this.scrollPos = {
       xcoord:0,
       ycoord:0
    };
  }

  scrollDown() {
    this.scrollPos = {
       xcoord: Math.min(this.scrollPos.xcoord + 5, this.frame.contentWindow.document.body.offsetHeight),
       ycoord: Math.min(this.scrollPos.ycoord + 5, this.frame.contentWindow.document.body.offsetHeight)
    };
    this.frame.contentWindow.scrollTo(this.scrollPos.xcoord,this.scrollPos.ycoord);
  }

  scrollUp() {
    this.scrollPos = {
       xcoord: Math.max(this.scrollPos.xcoord - 5, 0),
       ycoord: Math.max(this.scrollPos.ycoord - 5, 0)
    };
    this.frame.contentWindow.scrollTo(this.scrollPos.xcoord,this.scrollPos.ycoord);
  }

  render() {
    return (
      <div>
        <button onClick={this.scrollDown}>Scroll down</button>&nbsp;&nbsp;&nbsp;<button onClick={this.scrollUp}>Scroll up</button><br/><br/>
        <iframe ref={(c)=>{this.frame = c}} src="frame.html"></iframe>
      </div>
    );
  }
}

ScrollDetector.propTypes = {
}

ScrollDetector.defaultProps = {
}

export default ScrollDetector;
Read More
In some cases, System has to provide suggestions to user while user typing. Sending request for each and every request to server will be overhead. So sending request to server when user finishes typing will give good performance. We can detect whether user typing or finished his typing by delaying the onChange event.

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Program

Observer below code. Here we are using setTimeout for giving delays
import React from 'react';

class TypeDetector extends React.Component {

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      value:''
    }
  }

  handleChange(evt) {
    if(this._timeout){ //if there is already a timeout in process cancel it
        clearTimeout(this._timeout);
    }
    const val = evt.target.value;
    this._timeout = setTimeout(()=>{
       this._timeout = null;
       this.setState({
          value:val
       });
    },1000);
  }

  render() {
    return (
      <div>
        <div>
         Value :: <b>{this.state.value}</b><br/><br/>

        </div>
        <input style={{width:'300px', padding:'5px'}} placeholder="Enter text here" onChange={this.handleChange}/>
      </div>
    );
  }
}

TypeDetector.propTypes = {
}

TypeDetector.defaultProps = {
}

export default TypeDetector;
Read More
Whenever user scroll to the bottom, we can show Go to top button to make user reached to top of the page. This program will help you to find out bottom of the page.

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Program Flow

  1. Bind scroll event to window
  2. Calculate whole document height
  3. Get height of the window
  4. Calculate bottom of window
  5. If window bottom is greater than or equal to document height then user reached to bottom

ReactJS Component

import React from 'react';
import classNames from 'classnames';

class ScrollDetector extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      message:'not at bottom'
    };
    this.handleScroll = this.handleScroll.bind(this);
  }

  handleScroll() {
    const windowHeight = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
    const body = document.body;
    const html = document.documentElement;
    const docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight,  html.scrollHeight, html.offsetHeight);
    const windowBottom = windowHeight + window.pageYOffset;
    if (windowBottom >= docHeight) {
      this.setState({
        message:'bottom reached'
      });
    } else {
      this.setState({
        message:'not at bottom'
      });
    }
  }

  componentDidMount() {
    window.addEventListener("scroll", this.handleScroll);
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.handleScroll);
  }

  render() {
    return (
      <div>
        <div className="fixedDiv">{this.state.message}</div>
        <div className="scrollDiv"></div>
      </div>
    );
  }
}

ScrollDetector.propTypes = {
}

ScrollDetector.defaultProps = {
}

export default ScrollDetector;
Read More
Sometimes we need to pass some actions to parent component. Lets take menu as example. If user clicks on menu item, that menu item style should change, other menu items styles should reset to normal. How will you create this?, we need to attach callback to child components from parent component dynamically. Lets do this

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Markup

Lets take a simple markup of menu. Observe below code. If user clicks on li element, then background color of that li item should be green and other li items background color should be normal grey color. Lets build our components
<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
  <li>List Item 4</li>
  <li>List Item 5</li>
</ul>

ChildComponent.js

When user clicks on list item, parent callback function will be called with keyIndex
import React from 'react';
import classNames from 'classnames';

class ChildComponent extends React.Component {

  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.props.handleClick(this.props.keyIndex);
  }

  render() {
    return (
      <li className={classNames({'active':(this.props.selectedIndex === this.props.keyIndex)})} onClick={this.handleClick}>{this.props.children}</li>
    );
  }
}

ChildComponent.propTypes = {
   keyIndex:React.PropTypes.number
}

ChildComponent.defaultProps = {
}

export default ChildComponent;
This component creates li item.  

ParentComponent.js

This component creates ul item. Here in render function, We are cloning li items and attaching handleClick, keyIndex, selectedIndex  properties. Whenever user clicks on li item, handleClick callback will be called with keyIndex. Based on selectedIndex and keyIndex, background color of li item will change
import React from 'react';
import classNames from 'classnames';
import ValidComponentChildren from './ValidComponentChildren';

class ParentComponent extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      selectedIndex:-1
    }
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(keyIndex) {
    this.setState({
      selectedIndex:keyIndex
    });
  }

  render() {
    let keyIndexVal = 0;
    const items = ValidComponentChildren.map(this.props.children, child => {
      const childProps = child.props || {};
      keyIndexVal++;
      return React.cloneElement(child, {
        handleClick: this.handleClick,
        keyIndex:keyIndexVal,
        selectedIndex:this.state.selectedIndex
      }, childProps.children);
    });

    return (
      <ul>
        {items}
      </ul>
    );
   }
}

ParentComponent.propTypes = {
}

ParentComponent.defaultProps = {
}

export default ParentComponent;
Read More
It is really frustrating to write many functions to handle events on multiple elements. Here we can use Javascript closure concept to avoid multiple functions. Observe below code

To Run Example Code

execute below commands
npm install
npm start
now open index.html in browser

Program

Here commonFunction is handling click events on multiple elements by using Javascript closure concept
import React from 'react'

class ExampleApplication extends React.Component {

  constructor(props) {
    super(props);
    this.commonFunction = this.commonFunction.bind(this);
    this.state = {
      message:''
    };
  }

  commonFunction(itemName) {
    const _this = this;
    return function() {
      _this.setState({
        message:'clicked on '+itemName+'....take some action'
      });
    }
  }

  render() {
    return (
      <div>
         Click on below list items<br/><br/>
         <b>{this.state.message}</b><br/>
         <ul>
           <li onClick={this.commonFunction('item 1')}>List item 1</li>
           <li onClick={this.commonFunction('item 2')}>List item 2</li>
           <li onClick={this.commonFunction('item 3')}>List item 3</li>
           <li onClick={this.commonFunction('item 4')}>List item 4</li>
           <li onClick={this.commonFunction('item 5')}>List item 5</li>
         </ul>
      </div>
    );
  }

}

ExampleApplication.propTypes = {
}

ExampleApplication.defaultProps = {
}

export default ExampleApplication;
Read More
First of all we should now how module import works, I will give short description here. You can learn about modules by reading this article.  Now observe below screenshot.

To Run Example Code

execute below commands
npm install
webpack
now you can see dist folder with library files

React Library

We need to create react-library. It should not include any code from React, React-DOM. Whatever the components we develop, those components has to be available to import in other projects. Lets create small project 

Project

Observe below project structure. dist folder contains all JS and CSS library files. Component1.js, Component2.js  are the react component files.  index.js exports these components to create library. styles.scss contains styles in sass format

Component1.js

import React from 'react'

class Component extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
         Component 1
      </div>
    );
  }

}

ExampleApplication.propTypes = {
}

ExampleApplication.defaultProps = {
}

export default ExampleApplication;

Component2.js

import React from 'react'

class Component extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
         Component 2
      </div>
    );
  }

}

ExampleApplication.propTypes = {
}

ExampleApplication.defaultProps = {
}

export default ExampleApplication;

index.js

This file exports all components which has to be available for importing. Styles included in this file will be extracted using textExtractor webpack plugin, will be written to library CSS files
export Component1 from './Component1'
export Component2 from './Component2'

import styles from './styles.scss'

Webpack Configuration

Now we have to configure webpack.config.js.  Lets see what things we need to do with webpack
  1. Should convert ES6 code to ES5. (we can use babel to convert es6 to es5)
  2. Should generate library JS file without the code of React, React-dom (should include React, React-dom as externals)
  3. Should extract CSS, create minified CSS file (have to use TextExtracterPlugin)
  4. Should generate minified JS file along with react-library file (have to use Uglify plugin)

webpack.config.js

Observe below code. Here I used plugins as specified
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var webpack = require("webpack");

module.exports = {
  entry : {
    'react-library':'./src/index.js',
    'react-library.min':'./src/index.js'
  },

  output: {
    path: './dist',
    filename: '[name].js',
    library: 'ReactLibrary',
    libraryTarget: 'umd'
  },

  devtool: "source-map",

  externals: [
    {
      'react': {
        root: 'React',
        commonjs2: 'react',
        commonjs: 'react',
        amd: 'react'
      }
    },
    {
      'react-dom': {
        root: 'ReactDOM',
        commonjs2: 'react-dom',
        commonjs: 'react-dom',
        amd: 'react-dom'
      }
    }
  ],

  module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /(node_modules)/,
                loader: 'babel',
                query: {
                    presets: ['react','es2015','stage-0']
                }
            },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract("style", "css!sass")
      }
     ]
 },

 plugins: [
    new ExtractTextPlugin("./[name].css"),
    new webpack.optimize.UglifyJsPlugin({
     exclude:['react-library.js'],
     minimize: true,
     compress: { warnings: false }
   })
 ]
};

Package.json

Finally we have to build package.json which contains modules to details to install. 
{
  "name": "react-library",
  "version": "0.1.0",
  "description": "A sample setup to create react library with webpack",
  "main": "dist/react-library.js",
  "scripts": {
    "dist": "webpack"
  },
  "keywords": [
    "ReactJS",
    "WebPack"
  ],
  "author": "Srinivas Dasari",
  "license": "MIT",
  "devDependencies": {
    "react": "^15.2.1",
    "react-dom": "^15.2.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "webpack": "^1.13.0",
    "style-loader": "^0.13.1",
    "sass-loader": "^3.2.0",
    "css-loader": "^0.23.1",
    "node-sass":"^3.8.0",
    "babel-core": "^6.8.0",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0"
  }
}

Final Command

Finally run "webpack" command to generate dist folder.  You can run "npm run dist" command also. Once dist folder generated, you can copy this project and paste it in other projects node_modules folder.  Now you can import the components as normal way
import Component1 from 'react-library';
import Component2 from 'react-library';
Read More

Blogroll

Follow this blog by Email

Popular Posts