[“”, “!飛”, …, “馬”, “”], … [“”, “”, …, “飛”, “”], [“香”, “桂”, … “桂”, “香”], ], // mochigoma: (今回は省略), history: [ “77->76”, “33->34”, “88->22 nari” ] } satisfies Shogi // 棋譜状態 let shogiState = atom<Shogi>({...}) // 掴んだ座標 let selectedPosState = atom<Pos>({...}) // 掴んだ駒の可動域リスト let movableState = selector<Pos[]>({ key: "movableState", get: ({ get }) => { let {board} = get(shogiState) let pos = get(selectedPosState) return calculateMovable(board, pos) } }) // 駒コンポーネント let Koma = ({x, y}: Pos) => { let {board} = useRecoilValue(shogiState) let movables = useRecoilValue(movableState) let setSelectedPos = useSetRecoilValue(selectedPosState) return <button style={isIn(movables, x, y)} onClick={()=>setSelectedPos({x, y})}> {board[x][y]} </button> }