Skip to content

Instantly share code, notes, and snippets.

@GraceHanssen
Created April 22, 2021 20:38
Show Gist options
  • Save GraceHanssen/2516e5f7497239c5c1f87610efcf9d8e to your computer and use it in GitHub Desktop.
Save GraceHanssen/2516e5f7497239c5c1f87610efcf9d8e to your computer and use it in GitHub Desktop.
Grocery List
<div id="root"></div>
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
newItem: "",
list: []
};
}
//incorporating local storage
componentDidMount() {
this.hydrateStateWithLocalStorage();
// add event listener to save state to localStorage
// when user leaves/refreshes the page
window.addEventListener(
"beforeunload",
this.saveStateToLocalStorage.bind(this)
);
}
componentWillUnmount() {
window.removeEventListener(
"beforeunload",
this.saveStateToLocalStorage.bind(this)
);
// saves if component has a chance to unmount
this.saveStateToLocalStorage();
}
hydrateStateWithLocalStorage() {
// for all items in state
for (let key in this.state) {
// if the key exists in localStorage
if (localStorage.hasOwnProperty(key)) {
// get the key's value from localStorage
let value = localStorage.getItem(key);
// parse the localStorage string and setState
try {
value = JSON.parse(value);
this.setState({ [key]: value });
} catch (e) {
// handle empty string
this.setState({ [key]: value });
}
}
}
}
saveStateToLocalStorage() {
// for every item in React state
for (let key in this.state) {
// save to localStorage
localStorage.setItem(key, JSON.stringify(this.state[key]));
}
}
updateInput(key, value) {
// update react state
this.setState({ [key]: value });
}
addItem() {
// create a new item with unique id
const newItem = {
id: 1 + Math.random(),
value: this.state.newItem.slice()
};
// copy current list of items
const list = [...this.state.list];
// add the new item to the list
list.push(newItem);
// update state with new list, reset the new item input
this.setState({
list,
newItem: ""
});
}
deleteItem(id) {
// copy current list of items
const list = [...this.state.list];
// filter out the item being deleted
const updatedList = list.filter(item => item.id !== id);
this.setState({ list: updatedList });
}
render() {
return (
<div>
<h1 className="app-title">Grocery List</h1>
<div className="container">
<div
style={{
padding: 10,
textAlign: "left",
maxWidth: 2000,
margin: "auto"
}}
>
What items do you want to buy?
<br />
<input
type="text"
placeholder="Type here"
value={this.state.newItem}
onChange={e => this.updateInput("newItem", e.target.value)}
/>
<button
className="add-btn btn-floating"
onClick={() => this.addItem()}
disabled={!this.state.newItem.length}
>
<i class="material-icons"> Add new item </i>
</button>
<br />
<ul>
{this.state.list.map(item => {
return (
<li key={item.id}>
{item.value}
<button className="btn btn-floating" onClick={() => this.deleteItem(item.id)}>
<b class="material-icons">delete</b>
</button>
</li>
);
})}
</ul>
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
body{
background: white;
font-family: 'Oswald', montserrat;
font-size: 20px;
}
.btn{
background: white;
margin: 40px;
}
.add-btn{
padding: 10px;
background: #ccc;
width: 150px;
height: 40px;
}
.app-title{
padding: 10px;
color: #808080;
font-size: 40px;
}
input {
padding: 10px;
margin: 2px;
}
.container {
margin: 10px;
width: 700px;
border: 1.5px solid gray;
border-radius: 0px;
}
ul{
margin: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment