Usage with React
Designing Component Hierarchy
Our design brief is simple. We want to show a list of todo items. On click, a todo item is crossed out as completed. We want to show a field where the user may add a new todo. In the footer, we want to show a toggle to show all, only completed, or only active todos.
The following components and their props or atom state emerge from this brief:
TodoList
is a list showing visible todos. It filters the todos according to the current visibility filter.todos: Array
is an array of todo items with { id, text, completed } shape.visibilityFilter: string
is the current visibility filter.
Todo
is a single todo item.text: string
is the text to show.completed: boolean
is whether the todo should appear crossed out.onClick()
is a callback to invoke when the todo is clicked.
FilterLink
gets the current visibility filter and renders a link.filter: string
is the visibility filter it represents.
Footer
is where we let the user change currently visible todos.AddTodo
is an input field with an “Add” buttonApp
is the root component that renders everything else.
Implementing Components
Let's write the components!
components/Todo.js
components/TodoList.js
components/FilterLink.js
components/Footer.js
components/AddTodo.js
App.js
Passing the Store
All components need access to the store so they can use the hooks to update atoms and subscribe to them. One option would be to pass it as a prop to every container component. However it gets tedious, as you have to wire store even through presentational components just because they happen to render a container deep in the component tree.
The option we recommend is to use a special React component called <AtomRoot>
to magically make the store available to all components in the application without passing it explicitly. You only need to use it once when you render the root component: