React App sample code that implements useState accessing previous value. Using spread operator in raeact js. Dealing with complex states, mapping state data to html element.
src/components/App.js
import React, { useState } from "react";
import { TodoListItem } from "./TodoListItem";
function App() {
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);
function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}
function addItem() {
setItems((prevItems) => {
return [...prevItems, inputText];
});
setInputText("");
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input onChange={handleChange} type="text" value={inputText} />
<button onClick={addItem}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{items.map((todoItem) => (
<TodoListItem title={todoItem} />
))}
</ul>
</div>
</div>
);
}
export default App;
src/components/TodoListItem.js
import React, { useState } from "react";
export function TodoListItem(props) {
const [done, setStatus] = useState(false);
function clickHandler() {
setStatus((prevState) => {
return !prevState;
});
}
return (
<li
style={{ textDecoration: done
? "line-through"
: "none" }}
onClick={clickHandler}
>
{props.title}
</li>
);
}
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
ReactDOM.render(<App />, document.getElementById("root"));
public/style.css
body {
background-color: #ffeaa7;
min-height: 70vh;
padding: 1rem;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
color: hsl(198, 1%, 29%);
font-family: "Architects Daughter", cursive;
text-align: center;
font-size: 130%;
}
.container {
width: 100%;
height: auto;
min-height: 500px;
max-width: 500px;
min-width: 250px;
background: #f1f5f8;
background-image: radial-gradient(#bfc0c1 7.2%, transparent 0);
background-size: 25px 25px;
border-radius: 20px;
box-shadow: 4px 3px 7px 2px #00000040;
padding: 1rem;
box-sizing: border-box;
}
.heading {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
}
.heading h1 {
transform: rotate(2deg);
padding: 0.2rem 1.2rem;
border-radius: 20% 5% 20% 5%/5% 20% 25% 20%;
background-color: #fdcb6e;
font-size: 1.5rem;
}
.form input {
box-sizing: border-box;
background-color: transparent;
padding: 0.7rem;
border-bottom-right-radius: 15px 3px;
border-bottom-left-radius: 3px 15px;
border: solid 3px transparent;
border-bottom: dashed 3px #fdcb6e;
font-family: "Architects Daughter", cursive;
font-size: 1rem;
color: hsla(260, 2%, 25%, 0.7);
width: 70%;
margin-bottom: 20px;
}
button {
padding: 0;
border: none;
font-family: "Architects Daughter", cursive;
text-decoration: none;
padding-bottom: 3px;
border-radius: 5px;
background-color: #ffeaa7;
}
button span {
background: #f1f5f8;
display: block;
padding: 0.5rem 1rem;
border-radius: 5px;
border: 2px solid hsl(198, 1%, 29%);
}
li {
text-align: left;
position: relative;
padding: 0.5rem;
}