react/shells/dev/app/ToDoList/List.js

110 lines
2.4 KiB
JavaScript
Raw Normal View History

2019-01-23 03:04:37 +08:00
// @flow
import React, { Fragment, useCallback, useState } from 'react';
2019-01-23 03:04:37 +08:00
import ListItem from './ListItem';
import styles from './List.css';
export type Item = {|
id: number,
isComplete: boolean,
text: string,
|};
type Props = {||};
2019-01-24 00:45:19 +08:00
export default function List(props: Props) {
2019-01-23 03:04:37 +08:00
const [newItemText, setNewItemText] = useState<string>('');
const [items, setItems] = useState<Array<Item>>([
2019-01-24 00:45:19 +08:00
{ id: 1, isComplete: true, text: 'First' },
{ id: 2, isComplete: true, text: 'Second' },
{ id: 3, isComplete: false, text: 'Third' },
2019-01-23 03:04:37 +08:00
]);
const [uid, setUID] = useState<number>(4);
const handleClick = useCallback(() => {
if (newItemText !== '') {
setItems([
...items,
{
id: uid,
isComplete: false,
text: newItemText,
},
]);
setUID(uid + 1);
setNewItemText('');
2019-01-23 03:04:37 +08:00
}
}, [newItemText, items, uid]);
2019-01-23 03:04:37 +08:00
2019-01-24 00:45:19 +08:00
const handleKeyPress = useCallback(
event => {
if (event.key === 'Enter') {
handleClick();
}
},
[handleClick]
);
2019-01-23 03:04:37 +08:00
2019-01-24 00:45:19 +08:00
const handleChange = useCallback(
event => {
setNewItemText(event.currentTarget.value);
},
[setNewItemText]
);
2019-01-23 03:04:37 +08:00
2019-01-24 00:45:19 +08:00
const removeItem = useCallback(
itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
2019-01-24 00:45:19 +08:00
[items]
);
2019-01-23 03:04:37 +08:00
2019-01-24 00:45:19 +08:00
const toggleItem = useCallback(
itemToToggle => {
const index = items.indexOf(itemToToggle);
2019-01-23 03:04:37 +08:00
setItems(
items
.slice(0, index)
.concat({
...itemToToggle,
isComplete: !itemToToggle.isComplete,
})
.concat(items.slice(index + 1))
);
2019-01-24 00:45:19 +08:00
},
[items]
);
2019-01-23 03:04:37 +08:00
return (
<Fragment>
<h1>List</h1>
2019-01-23 03:04:37 +08:00
<input
type="text"
placeholder="New list item..."
className={styles.Input}
value={newItemText}
onChange={handleChange}
onKeyPress={handleKeyPress}
/>
<button
className={styles.IconButton}
disabled={newItemText === ''}
onClick={handleClick}
2019-01-24 00:45:19 +08:00
>
<span role="img" aria-label="Add item">
</span>
</button>
2019-01-23 03:04:37 +08:00
<ul className={styles.List}>
{items.map(item => (
<ListItem
key={item.id}
item={item}
removeItem={removeItem}
toggleItem={toggleItem}
/>
))}
</ul>
</Fragment>
2019-01-23 03:04:37 +08:00
);
2019-01-24 00:45:19 +08:00
}