728x90
// App.tsx
import React from 'react';
import { createGlobalStyle } from 'styled-components';
import {darkTheme,lightTheme} from "./theme"
import ToDoList from './components/ToDoList';
const GlobalStyle = createGlobalStyle`
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400&display=swap');
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, menu, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
display: block;
}
/* HTML5 hidden-attribute fix for newer browsers */
*[hidden] {
display: none;
}
body {
line-height: 1;
}
menu, ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
* {
box-sizing: border-box;
}
body {
font-family: 'Source Sans Pro', sans-serif;
background-color:white;
/* App provider는 theme에 접근할수있기 때문에 props사용
가능 */
color:black;
}
a {
text-decoration:none;
color: inherit;
/* color는 부모에게서 가져오라고 함 */
}
`;
function App() {
return (
<>
<GlobalStyle/>
<ToDoList/>
</>
);
}
export default App;
// atoms.tsx
import { atom, selector } from "recoil";
import { recoilPersist } from "recoil-persist";
const { persistAtom } = recoilPersist({
key:"recoil-persist",
storage: localStorage,
});
// enumerable의 약자로 열거가능한 이라는뜻
// protectable하게 만들기 위해서 각각의 string들을
// enum은 기본적으로 숫자다.
// 그래서 실제로는 0,1,2 순이다.
export enum Categories{
"TO_DO" ,
"DOING",
"DONE",
}
export interface IToDo{
text:string;
id: number;
category: Categories;
// 이 세개중에 한개를 사용해야한다.
}
export const categoryState = atom<Categories>({
key:"category",
default:Categories.TO_DO,
});
export const toDoState = atom<IToDo[]>({
// atom은 key, default가 항상 필요
key: "toDO",
default:[],
// localstrage를 위해 추가
effects_UNSTABLE: [persistAtom],
});
// selector를 이용해서 state를 변화시킬 수 있다.
// state자체를 바꾸는것이 아니라 그 output을 바꾸고 있다.
// selector는 세개의 배열을 담은 하나의 배열을 return하고 있다.
export const toDoSelector = selector({
key:"toDoSelector",
get:({ get }) =>{
const toDos = get(toDoState);
const category = get(categoryState);
return toDos.filter((toDo) => toDo.category === category);
},
});
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RecoilRoot } from 'recoil';
import {ThemeProvider} from "styled-components";
import App from './App';
import { darkTheme,lightTheme } from './theme';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<RecoilRoot>
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
</RecoilRoot>
</React.StrictMode>
);
// theme.ts
/* styled 파일에 정의된 속성들과 똑같아야함
*/
import { DefaultTheme } from "styled-components";
export const darkTheme:DefaultTheme = {
textColor: "#f5f6fa",
bgColor: "black",
accentColor: "#fbc531"
}
export const lightTheme:DefaultTheme = {
textColor: "f5f6fa",
bgColor: "whitesmoke",
accentColor: "#fbc531"
}
728x90
'Frontend > React' 카테고리의 다른 글
ToDoList에 localstorage 만들기 (0) | 2023.01.31 |
---|---|
(20) React -To Do App(Components) (2) (0) | 2023.01.26 |
(18) React - selector modify (0) | 2023.01.25 |
(17) React- React hook form (0) | 2023.01.23 |
(16) React- Recoil (0) | 2023.01.21 |