commit
a20d2c5eaa
@ -0,0 +1,178 @@
|
||||
<div align="center">
|
||||
<h1> 30 Days Of React: Uncontrolled Component</h1>
|
||||
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
|
||||
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
|
||||
</a>
|
||||
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
|
||||
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
|
||||
</a>
|
||||
|
||||
<sub>Author:
|
||||
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
|
||||
<small> October, 2020</small>
|
||||
</sub>
|
||||
|
||||
</div>
|
||||
|
||||
[<< Day 12](../12_Day_Forms/12_forms.md) | [Day 14 >>]()
|
||||
|
||||

|
||||
|
||||
- [Uncotrolled Components](#uncotrolled-components)
|
||||
- [Getting data from an uncontrolled input](#getting-data-from-an-uncontrolled-input)
|
||||
- [Getting multiple input data from form](#getting-multiple-input-data-from-form)
|
||||
- [Exercises](#exercises)
|
||||
- [Exercises: Level 1](#exercises-level-1)
|
||||
- [Exercises: Level 2](#exercises-level-2)
|
||||
- [Exercises: Level 3](#exercises-level-3)
|
||||
|
||||
# Uncotrolled Components
|
||||
|
||||
In the previous day challenge we have covered controlled inputs. In react most of the time we use controlled inputs as recommended on the official [documentation of React](https://reactjs.org/docs/uncontrolled-components.html).
|
||||
|
||||
To write an uncontrolled component, instead of writing an event handler for every state update, you can use a ref to get form values from the DOM. In uncontrolled input we get data from input fields like traditional HTML form data handling.
|
||||
|
||||
An example of uncontrolled component
|
||||
|
||||
## Getting data from an uncontrolled input
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
||||
class App extends Component {
|
||||
firstName = React.createRef()
|
||||
|
||||
handleSubmit = (e) => {
|
||||
e.preventDefault()
|
||||
console.log(this.firstName.current.value)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='App'>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label htmlFor='firstName'>First Name: </label>
|
||||
<input
|
||||
type='text'
|
||||
id='firstName'
|
||||
name='firstName'
|
||||
placeholder='First Name'
|
||||
ref={this.firstName}
|
||||
/>
|
||||
<button type='submit'>Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const rootElement = document.getElementById('root')
|
||||
ReactDOM.render(<App />, rootElement)
|
||||
```
|
||||
|
||||
## Getting multiple input data from form
|
||||
|
||||
We can grab multiple input data from DOM. We are not directly targeting the DOM but React is getting data from DOM using ref.
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
||||
class App extends Component {
|
||||
firstName = React.createRef()
|
||||
lastName = React.createRef()
|
||||
country = React.createRef()
|
||||
title = React.createRef()
|
||||
|
||||
handleSubmit = (e) => {
|
||||
// stops the default behavior of form element specifically refreshing of page
|
||||
e.preventDefault()
|
||||
|
||||
console.log(this.firstName.current.value)
|
||||
console.log(this.lastName.current.value)
|
||||
console.log(this.title.current.value)
|
||||
console.log(this.country.current.value)
|
||||
|
||||
const data = {
|
||||
firstName: this.firstName.current.value,
|
||||
lastName: this.lastName.current.value,
|
||||
title: this.title.current.value,
|
||||
country: this.country.current.value,
|
||||
}
|
||||
// the is the place we connect backend api to send the data to the database
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='App'>
|
||||
<h3>Add Student</h3>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='firstName'
|
||||
placeholder='First Name'
|
||||
ref={this.firstName}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='lastName'
|
||||
placeholder='Last Name'
|
||||
ref={this.lastName}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='country'
|
||||
placeholder='Country'
|
||||
ref={this.country}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='title'
|
||||
placeholder='Title'
|
||||
ref={this.title}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button className='btn btn-success'>Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const rootElement = document.getElementById('root')
|
||||
ReactDOM.render(<App />, rootElement)
|
||||
```
|
||||
|
||||
Most of the time we use controlled input instead of uncontrolled input. In case if you want to target some element on the DOM you will use ref to get the content of that element. Don't touch directly using pure JavaScript. When you develop a React application do not touch the DOM directly because React has its own way of handling the DOM manipulation.
|
||||
|
||||
# Exercises
|
||||
|
||||
## Exercises: Level 1
|
||||
|
||||
1. What is a controlled input?
|
||||
2. What is an uncontrolled input
|
||||
3. How do you get a content of a certain HTML element in React ?
|
||||
4. Why it is not a good idea to touch the DOM directly in React ?
|
||||
5. What is most frequently used in React ? Controlled or Uncontrolled input.
|
||||
|
||||
## Exercises: Level 2
|
||||
|
||||
## Exercises: Level 3
|
||||
|
||||
🎉 CONGRATULATIONS ! 🎉
|
||||
|
||||
[<< Day 12](../12_Day_Forms/12_forms.md) | [Day 14 >>]()
|
@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
@ -0,0 +1,5 @@
|
||||
# 30 Days of React App: Day 13
|
||||
|
||||
In the project directory, you can run to start the project
|
||||
|
||||
### `npm start`
|
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "30-days-of-react",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "3.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
|
||||
<title>30 Days Of React App</title>
|
||||
<style>
|
||||
|
||||
/* == General style === */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
line-height: 1.5;
|
||||
font-family: 'Montserrat';
|
||||
font-weight: 300;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.root {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-wrapper,
|
||||
.main-wrapper,
|
||||
.footer-wrapper {
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.header-wrapper,
|
||||
.main-wrapper {
|
||||
padding: 10px;
|
||||
margin: 2px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 70px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #61dbfb;
|
||||
padding: 25;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 10px;
|
||||
padding-bottom: 60px;
|
||||
/* Height of the footer */
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
/* Height of the footer */
|
||||
background: #6cf;
|
||||
}
|
||||
|
||||
.footer-wrapper {
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
}
|
||||
.user-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.user-card > img {
|
||||
border-radius: 50%;
|
||||
width: 14%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@
|
||||
export const tenHighestPopulation = [
|
||||
{ country: 'World', population: 7693165599 },
|
||||
{ country: 'China', population: 1377422166 },
|
||||
{ country: 'India', population: 1295210000 },
|
||||
{ country: 'United States of America', population: 323947000 },
|
||||
{ country: 'Indonesia', population: 258705000 },
|
||||
{ country: 'Brazil', population: 206135893 },
|
||||
{ country: 'Pakistan', population: 194125062 },
|
||||
{ country: 'Nigeria', population: 186988000 },
|
||||
{ country: 'Bangladesh', population: 161006790 },
|
||||
{ country: 'Russian Federation', population: 146599183 },
|
||||
{ country: 'Japan', population: 126960000 },
|
||||
]
|
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 40 KiB |
@ -0,0 +1,79 @@
|
||||
import React, { Component } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
||||
class App extends Component {
|
||||
firstName = React.createRef()
|
||||
lastName = React.createRef()
|
||||
country = React.createRef()
|
||||
title = React.createRef()
|
||||
|
||||
handleSubmit = (e) => {
|
||||
// stops the default behavior of form element specifically refreshing of page
|
||||
e.preventDefault()
|
||||
|
||||
console.log(this.firstName.current.value)
|
||||
console.log(this.lastName.current.value)
|
||||
console.log(this.title.current.value)
|
||||
console.log(this.country.current.value)
|
||||
|
||||
const data = {
|
||||
firstName: this.firstName.current.value,
|
||||
lastName: this.lastName.current.value,
|
||||
title: this.title.current.value,
|
||||
country: this.country.current.value,
|
||||
}
|
||||
// the is the place we connect backend api to send the data to the database
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='App'>
|
||||
<h3>Add Student</h3>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='firstName'
|
||||
placeholder='First Name'
|
||||
ref={this.firstName}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='lastName'
|
||||
placeholder='Last Name'
|
||||
ref={this.lastName}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='country'
|
||||
placeholder='Country'
|
||||
ref={this.country}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='text'
|
||||
name='title'
|
||||
placeholder='Title'
|
||||
ref={this.title}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button className='btn btn-success'>Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const rootElement = document.getElementById('root')
|
||||
ReactDOM.render(<App />, rootElement)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue