DEV Community

Cover image for Recoil Todo Example
Ryota Murakami
Ryota Murakami

Posted on

Recoil Todo Example

View Source & interact

Screen Shot 2020-10-01 at 12.08.24

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! πŸ€—

Discussion (0)