View Source & interact
Little explanation
I migrated Recoil at state management but still Recoil is new library, can't see almost common example now.
So I left simple way Recoil todo that only use <RecoilRoot>
and useRecoilState
of Recoil API.
Entire Code is huge amount for paste here, I'll show you only 2 files that Recoil API using point.
index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Router } from '@reach/router'
import { RecoilRoot } from 'recoil'
import App from './App'
import ErrorBoundary from './ErrorBoundary'
import { NotFound } from './NotFound'
import { Routes } from './dataStructure'
interface Props {
path: Routes
}
const Controller: React.FC<Props> = ({ path }) => <App path={path} />
ReactDOM.render(
<ErrorBoundary>
<RecoilRoot>
<Router>
<Controller path="/" />
<Controller path="/active" />
<Controller path="/completed" />
<NotFound default />
</Router>
</RecoilRoot>
</ErrorBoundary>,
document.getElementById('root')
)
TodoList.tsx
import React, { ReactElement } from 'react'
import Item from './Item'
import { useRecoilState } from 'recoil'
import { Layout } from './style'
import { AppState, initialAppState, Routes, Todo } from '../../dataStructure'
interface Props {
path: Routes
}
const TodoList: React.FC<Props> = ({ path }) => {
const [appState, setAppState] = useRecoilState<AppState>(initialAppState)
function toggleAllCheckbox(e: React.ChangeEvent<HTMLInputElement>): void { /* eslint-disable-line prettier/prettier */
// reverse all todo.completed: boolean flag
setAppState({ todoList: appState.todoList.map((t: Todo): Todo => ({ ...t, completed: e.target.checked })) }) /* eslint-disable-line prettier/prettier */
}
return (
<Layout>
<section className="main">
<input
id="toggle-all"
className="toggle-all"
type="checkbox"
onChange={toggleAllCheckbox}
data-cy="toggle-all-btn"
data-testid="toggle-all-btn"
/>
<label htmlFor="toggle-all">Mark all as complete</label>
<ul className="todo-list" data-testid="todo-list">
{appState.todoList
.filter((t: Todo): boolean => {
switch (path) {
case '/':
return true
case '/active':
return t.completed === false
case '/completed':
return t.completed === true
default:
return true
}
})
.map(
(t: Todo): ReactElement => {
return <Item key={t.id} todo={t} />
}
)}
</ul>
</section>
</Layout>
)
}
export default TodoList
Conclusion
Recoil has more scalable API such as Selector, Snapshot.
My implementation is library agonistic style.
Thank you for reading the post! ๐ค