React

by Abdul Ahmad

HTML

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

SCSS

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

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

li {
  margin: 8px 0;
}

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

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


.input-wrap {
  margin-top: 20px;
  input {
    padding: 10px;
    margin-top: 5px;
  }
}

React

function App() {
	const formState = {
    email: '',
    firstName: '',
    lastName: '',
    phoneNumber: '',
    password: '',
  };
  const [formReadyToSubmit, setFormReadyToSubmit] = React.useState(false);

	function onChange(e) {
    try {
  		formState[e.target.name] = e.target.value;
      validateForm({ formState });
      setFormReadyToSubmit(true);
    } catch (e) {
      console.log('e', e);
    }
  }
  
  const { email, firstName, lastName, phoneNumber, password } = formState;

	return (
  	<form className='form-box'>
      <Input name='email' value={email} onChange={onChange} />
      <Input name='firstName' value={firstName} onChange={onChange} />
      <Input name='lastName' value={lastName} onChange={onChange} />
      <Input name='phoneNumber' value={phoneNumber} onChange={onChange} />
      <Input name='password' value={password} onChange={onChange} />
  	</form>
  );
}

function Input({ name, value: initialValue, onChange, setFormReadyToSubmit }) {
	const [value, setValue] = React.useState(initialValue || '');
	const onChangeLocal = (e) => {
    setValue(e.target.value);
    onChange(e);
  }
  console.log('rendering input: ', name);
	return (
  	<div className='input-wrap'>
      <div>{name}</div> 
      <input 
        value={value} 
        onChange={onChangeLocal} 
        name={name} 
      />
    </div>
  );
}

function validateForm({ formState } = {}) {
	if (!formState) throw ('no form state provided');
  
  const errors = [];
  Object.entries(formState).forEach(([k, v]) => {
  	if (!v) {
    	errors.push({ 
      	field: k, 
        message: 'value for ' + k + ' required'
      });
    }
  });
  
  if (errors.length > 0) throw(errors);
}

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