Decoration of Components

Using decoration to validate textfields

by phollome

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

class App extends React.Component {
  render() {
    return (
      <div>
        <Email />
        <Number />
      </div>
    );
  }
}

class Textfield extends React.Component {
	constructor(props) {
  	super(props);
    this.state = {
    	value: '',
    };
  }
	handleChange = (evt) => {
  	this.setState({value: evt.target.value});
    if (this.props.validate) {
    	this.props.validate(this.state.value);
    }
  }
	render () {
  	const { valid, } = this.props;
    if (valid === true) {
    	console.log(valid);
    }
  	return (
    	<React.Fragment>
        <input {...this.state} onChange={this.handleChange} />
        <p>{`valid? ${valid}`}</p>
      </React.Fragment>
    );
  }
}

const validate = (validator) => (Component) => {
	return class extends React.Component {
  	constructor (props) {
    	super(props);
      this.state = {
      	valid: false,
      };
    }
  	validate = (value) => {
    	console.log('validte');
    	this.setState({ valid: validator(value), });
    }
    render() {
    	return (<Component {...this.props} {...this.state} validate={this.validate}></Component>)
    }
  }
}

const Email = validate((value) => value.includes('@'))(Textfield);

@validate((value) => /^[0-9]+$/.test(value))
class Number extends Textfield {}

ReactDOM.render(<App />, document.querySelector("#app"))