🌀

Recoilやってみた

2022/01/13に公開

公式のチュートリアルをやってみました
ファイル名やimportが明記されていなくてわかりにくかったので、
ここに記載しておきます
https://recoiljs.org/docs/basic-tutorial/atoms

create-react-app

npx create-react-app recoil-app
cd recoil-app

install

npm install --save recoil

source

最終的な構成
recoil-app $ tree src
src
├── App.css
├── App.js
├── App.test.js
├── RecoilState.js
├── TodoItem.js
├── TodoItemCreator.js
├── TodoList.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
└── setupTests.js

0 directories, 12 files
RecoilState.js
import { atom } from 'recoil';

export const todoListState = atom({
  key: 'todoListState',
  default: [],
});
App.js
import { TodoList } from './TodoList';
import { RecoilRoot } from 'recoil';

const App = () =>  {
  return (
    <RecoilRoot>
      <h1>Todo List</h1>
      <TodoList/>
    </RecoilRoot>
  );
}

export default App;
TodoList.js
import { useRecoilValue } from 'recoil';
import { todoListState } from "./RecoilState";
import { TodoItemCreator } from './TodoItemCreator';
import { TodoItem } from './TodoItem';

export const TodoList = () => {
    const todoList = useRecoilValue(todoListState);

    return (
        <>
        <TodoItemCreator />

        {todoList.map((todoItem) => (
            <TodoItem key={todoItem.id} item={todoItem} />
        ))}
        </>
    );
}
TodoItemCreator.js
import React from 'react';
import { useSetRecoilState } from 'recoil';
import { todoListState } from "./RecoilState";

export const TodoItemCreator = () =>  {
    const [inputValue, setInputValue] = React.useState('');
    const setTodoList = useSetRecoilState(todoListState);
  
    const addItem = () => {
      setTodoList((oldTodoList) => [
        ...oldTodoList,
        {
          id: getId(),
          text: inputValue,
          isComplete: false,
        },
      ]);
      setInputValue('');
    };
  
    const onChange = ({target: {value}}) => {
      setInputValue(value);
    };
  
    return (
      <div>
        <input type="text" value={inputValue} onChange={onChange} />
        <button onClick={addItem}>Add</button>
      </div>
    );
  }
  
  // utility for creating unique Id
  let id = 0;
  function getId() {
    return id++;
  }
TodoItem.js
import { useRecoilState } from "recoil";
import { todoListState } from "./RecoilState";

export const TodoItem = ({item}) => {
    const [todoList, setTodoList] = useRecoilState(todoListState);
    const index = todoList.findIndex((listItem) => listItem === item);
  
    const editItemText = ({target: {value}}) => {
      const newList = replaceItemAtIndex(todoList, index, {
        ...item,
        text: value,
      });
  
      setTodoList(newList);
    };
  
    const toggleItemCompletion = () => {
      const newList = replaceItemAtIndex(todoList, index, {
        ...item,
        isComplete: !item.isComplete,
      });
  
      setTodoList(newList);
    };
  
    const deleteItem = () => {
      const newList = removeItemAtIndex(todoList, index);
  
      setTodoList(newList);
    };
  
    return (
      <div>
        <input type="text" value={item.text} onChange={editItemText} />
        <input
          type="checkbox"
          checked={item.isComplete}
          onChange={toggleItemCompletion}
        />
        <button onClick={deleteItem}>X</button>
      </div>
    );
  }
  
  function replaceItemAtIndex(arr, index, newValue) {
    return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)];
  }
  
  function removeItemAtIndex(arr, index) {
    return [...arr.slice(0, index), ...arr.slice(index + 1)];
  }

run

npm start

Discussion