🌀
Recoilやってみた
公式のチュートリアルをやってみました
ファイル名やimportが明記されていなくてわかりにくかったので、
ここに記載しておきます
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