import React, { Component } from 'react';

import PropTypes from 'prop-types';
import isString from 'lodash.isstring';
import result from 'lodash.result';

export default class DatString extends Component {
  static propTypes = {
    data: PropTypes.object,
    path: PropTypes.string,
    label: PropTypes.string,
    labelWidth: PropTypes.number,
    liveUpdate: PropTypes.bool,
    onUpdate: PropTypes.func,
    _onUpdateValue: PropTypes.func
  };

  state = {
    value: this.getValue()
  };

  componentWillReceiveProps(nextProps) {
    this.setState({
      value: this.getValue(nextProps)
    });
  }

  getValue(props = this.props) {
    return result(props.data, props.path);
  }

  handleChange = event => {
    const { value } = event.target;

    this.setState({ value }, () => {
      this.props.liveUpdate && this.update();
    });
  };

  handleFocus = () => {
    document.addEventListener('keydown', this.handleKeyDown);
  };

  handleBlur = () => {
    document.removeEventListener('keydown', this.handleKeyDown);
    window.getSelection().removeAllRanges();
    !this.props.liveUpdate && this.update();
  };

  handleKeyDown = event => {
    const key = event.keyCode || event.which;

    if (key === 13) {
      !this.props.liveUpdate && this.update();
    }
  };

  update() {
    const { value } = this.state;

    this.props._onUpdateValue &&
      this.props._onUpdateValue(this.props.path, value);
    this.props.onUpdate && this.props.onUpdate(value);
  }

  render() {
    const { path, label, labelWidth } = this.props;
    const labelText = isString(label) ? label : path;

    return (
      <li className="cr string">
        <label>
          <span className="label-text" style={{ width: `${labelWidth}%` }}>
            {labelText}
          </span>
          <input
            type="text"
            value={this.state.value}
            style={{ width: `${100 - labelWidth}%` }}
            onChange={this.handleChange}
            onFocus={this.handleFocus}
            onBlur={this.handleBlur}
          />
        </label>
      </li>
    );
  }
}

@@ -455,87 +455,212 @@
 stat
-e = %7B%0A    value: this.getValue()%0A  %7D;%0A%0A  componentWillReceiveProps(nextProps) %7B
+ic defaultProps = %7B%0A    data: null,%0A    path: null,%0A    label: null,%0A    labelWidth: 40,%0A    liveUpdate: true,%0A    onUpdate: () =%3E null,%0A    _onUpdateValue: () =%3E null%0A  %7D;%0A%0A  constructor() %7B%0A    super();
 %0A   
@@ -666,24 +666,23 @@
   this.s
-etS
 tate
-(
+ = 
 %7B%0A      
@@ -692,39 +692,18 @@
 ue: 
-this.getValue(nextProps)
+null
 %0A    %7D
-)
 ;%0A  
@@ -711,57 +711,93 @@
 %0A%0A  
-getValue(props = this.props) %7B%0A    return
+static getDerivedStateFromProps(nextProps, prevState) %7B%0A    const nextValue =
  result(
 prop
@@ -792,17 +792,21 @@
  result(
-p
+nextP
 rops.dat
@@ -808,17 +808,21 @@
 s.data, 
-p
+nextP
 rops.pat
@@ -824,16 +824,113 @@
 s.path);
+%0A%0A    if (prevState.value === nextValue) return null;%0A%0A    return %7B%0A      value: nextValue%0A    %7D;
 %0A  %7D%0A%0A  
@@ -995,63 +995,56 @@
 et;%0A
-%0A
     
-this.setState(%7B value %7D, () =%3E %7B%0A      this.props.
+const %7B liveUpdate %7D = this.props;%0A%0A    if (
 live
@@ -1041,35 +1041,33 @@
   if (liveUpdate
- &&
+)
  this.update();%0A
@@ -1063,24 +1063,21 @@
 .update(
-);%0A    %7D
+value
 );%0A  %7D;%0A
@@ -1302,32 +1302,65 @@
 nges();%0A
+%0A
     
-!this.props.
+const %7B liveUpdate %7D = this.props;%0A    if (!
 liveUpda
@@ -1353,35 +1353,33 @@
  if (!liveUpdate
- &&
+)
  this.update();%0A
@@ -1463,49 +1463,71 @@
 ch;%0A
-%0A    if (key === 13) %7B%0A      !this.props.
+    const %7B liveUpdate %7D = this.props;%0A%0A    if (key === 13 && !
 live
@@ -1528,27 +1528,25 @@
  !liveUpdate
- &&
+)
  this.update
@@ -1553,14 +1553,8 @@
 ();%0A
-    %7D%0A
   %7D;
@@ -1564,16 +1564,21 @@
  update(
+value
 ) %7B%0A    
@@ -1589,69 +1589,42 @@
 t %7B 
-value %7D = this.state;%0A%0A    this.props._onUpdateValue &&%0A     
+_onUpdateValue, onUpdate, path %7D =
  thi
@@ -1630,17 +1630,22 @@
 is.props
-.
+;%0A    
 _onUpdat
@@ -1651,27 +1651,16 @@
 teValue(
-this.props.
 path, va
@@ -1673,42 +1673,8 @@
     
-this.props.onUpdate && this.props.
 onUp

fix linting errors and implement getDerivedStateFromProps