Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- setDate
- React
- includes()
- 3진수
- Eventlitener
- useState()
- charAt()
- useEffect()
- indexOf()
- substring()
- 소수점 올림내림
- map()
- slice()
- 항해99솔직후기 #항해99장점 #항해99단점 #부트캠프추천
- filter()
- toUpperCase()
- parseInt()
- reat if문
- jsx반복문
- 차집합
- isNaN()
- new Date()
- getday()
- repeat()
- Math.floor()
- Number()
- sort()
- 교집합
- Math.sqrt()
- useRef()
Archives
- Today
- Total
개발자로 전향중
리액트 4주차 mydictionary 2022-01-28 기능구현 완료! 본문
기능구현 완료!
App.js
import { Route, Routes } from "react-router-dom";
import React from "react";
import Page from "./Page";
import AddPage from "./addPage";
import DetailPage from "./detailPage";
function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Page />} />
<Route path="/addpage" element={<AddPage />} />
<Route path="/detailpage:index" element={<DetailPage />} />
</Routes>
</div>
);
}
export default App;
Page.js
import React from "react";
import styled from "styled-components";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux"
import { IoIosAddCircle } from "react-icons/io";
import { useDispatch } from "react-redux";
import { updateDic, deleteDic } from "./redux/modules/dic";
const Page = () => {
const dispatch = useDispatch();
let navigate = useNavigate();
const inputs = useSelector((state) => state.dic.inputs);
return (
<>
<Title>My Dictionary</Title>
<IoIosAddCircle size={50} color="purple"
onClick={() => { navigate("/addpage"); }} />
<Line />
<Container>
{inputs.map((input, index) => {
return (
<Input key={index} completed={input.completed}>
<h4 style={{
fontSize: "24px"
}}>{input.word}</h4>
<span>[{input.mean}]</span>
<p>{input.explain}</p>
<p>{input.example}</p>
<p>{input.same}</p>
<button onClick={() => {
dispatch(updateDic(index));
}}>완료</button>
<button onClick={() => {
navigate("/detailpage"+index);
}}>수정</button>
<button onClick={() => {
dispatch(deleteDic(index));
}}>삭제</button>
</Input>
);
})}
</Container>
</>
);
};
const Title = styled.h1`
color: slateblue;
text-align: center;
`;
const Line = styled.hr`
margin: 16px 10px;
border: 2px dotted #ddd;
`;
const Container = styled.div`
max-width: 80vw;
min-height: 100vh;
background-color: #FFFAFA;
padding: 30px;
margin: 100px auto;
border-radius: 5px;
border: 1px solid #D8BFD8;
`;
// props는 Input의 props를 넘겨주는 것! 자바스크립트를 쓰려면 ${}를 넣어줘야함
const Input = styled.div`
background-color: ${(inputs) => (inputs.completed ? "#673ab7" : "#E6E6FA")};
border-radius: 10px;
border: 1px solid #D8BFD8;
width: 20vw;
float: left;
margin: 10px 20px
`;
export default Page;
addPage.js
// 리액트 패키지를 불러옵니다.
import React from 'react';
import styled from "styled-components";
import { useDispatch } from "react-redux";
import { createDic } from "./redux/modules/dic"
import { useNavigate } from "react-router-dom";
import Button from '@mui/material/Button';
const AddPage = () => {
let navigate = useNavigate();
const word = React.useRef(null);
const mean = React.useRef(null);
const explain = React.useRef(null);
const example = React.useRef(null);
const same = React.useRef(null);
const dispatch = useDispatch();
const addDictList = () => {
if (word.current.value === "") {
window.location = "/addpage"
alert("단어를 입력해주세요")
} else if (explain.current.value === "") {
window.location = "/addpage"
alert("설명을 입력해주세요")
} else if (example.current.value === "") {
window.location = "/addpage"
alert("예시를 입력해주세요")
} else {
dispatch(createDic({
word: word.current.value,
explain: explain.current.value,
example: example.current.value,
mean : mean.current.value,
same : same.current.value,
completed: false,
}
));
}
};
return (
<>
<Container>
<Title>내 사전</Title>
<Line />
<ItemStyle>
<Input>
<input name="name" placeholder="단어" ref={word} />
</Input>
<Input>
<input name="mean" placeholder="뜻" ref={mean} />
</Input>
<Input>
<input name="explain" placeholder="설명" ref={explain} />
</Input>
<Input>
<input name="example" placeholder="예시문" ref={example} />
</Input>
<Input>
<input name="same" placeholder="비슷한단어" ref={same} />
</Input>
<Button
style={style.button}
variant='outlined'
color='secondary'
onClick={() => {
addDictList();
// 온클릭 중복하려면 뒤에() 붙여야한다
navigate("/");
}}>추가하기</Button>
</ItemStyle>
</Container>
</>
);
};
export default AddPage;
const style = {
button: {
width: "90%",
display: "block",
margin: "30px auto 0px auto",
padding: "5px"
},
text: {
textAlign: "center"
}
}
const Container = styled.div`
max-width: 350px;
min-height: 60vh;
background-color: #FFFAFA;
padding: 16px;
margin: 100px auto;
border-radius: 5px;
border: 1px solid #ddd;
`;
const Title = styled.h1`
color: slateblue;
text-align: center;
`;
const Line = styled.hr`
margin: 16px 10px;
border: 2px dotted #ddd;
`;
const ItemStyle = styled.div`
padding: 5px;
margin: 50px 8px 8px 8px;
background-color: #E6E6FA;
line-height: 20px
`;
const Input = styled.div`
max-width: "100%",
min-height: 20vh;
background-color: #E6E6FA;
padding: 10px;
margin: 10px 10px;
display: flex;
& > * {
padding : 10px;
}
& input{
border: 1px solid #888;
width: 100%;
}
& input:focus {
border: 1px solid #a673ff;
outline: none;
}
`;
detailPage.js
// 리액트 패키지를 불러옵니다.
import React from 'react';
import styled from "styled-components";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import Button from '@mui/material/Button';
import { amendDic } from "./redux/modules/dic"
import { useParams } from "react-router-dom";
const DetailPage = (props) => {
const {index} = useParams();
const dic_index = {index}.index
let navigate = useNavigate();
const word = React.useRef(null);
const mean = React.useRef(null);
const explain = React.useRef(null);
const example = React.useRef(null);
const same = React.useRef(null);
const dispatch = useDispatch();
const amendDictList = () => {
if (word.current.value === "") {
window.location = "/addpage"
alert("단어를 입력해주세요")
} else if (explain.current.value === "") {
window.location = "/addpage"
alert("설명을 입력해주세요")
} else if (example.current.value === "") {
window.location = "/addpage"
alert("예시를 입력해주세요")
} else {
dispatch(amendDic({
word: word.current.value,
explain: explain.current.value,
example: example.current.value,
mean : mean.current.value,
same : same.current.value,
completed: false,
index : dic_index
}
));
}
};
return (
<>
<Container>
<Title>내 사전</Title>
<Line />
<ItemStyle>
<Input>
<input name="name" placeholder="단어" ref={word} />
</Input>
<Input>
<input name="mean" placeholder="뜻" ref={mean} />
</Input>
<Input>
<input name="explain" placeholder="설명" ref={explain} />
</Input>
<Input>
<input name="example" placeholder="예시문" ref={example} />
</Input>
<Input>
<input name="same" placeholder="비슷한단어" ref={same} />
</Input>
<Button
style={style.button}
variant='outlined'
color='secondary'
onClick={() => {
amendDictList();
// 온클릭 중복하려면 뒤에() 붙여야한다
navigate("/");
}}>수정하기</Button>
</ItemStyle>
</Container>
</>
);
};
export default DetailPage;
const style = {
button: {
width: "90%",
display: "block",
margin: "30px auto 0px auto",
padding: "5px"
},
text: {
textAlign: "center"
}
}
const Container = styled.div`
max-width: 350px;
min-height: 60vh;
background-color: #FFFAFA;
padding: 16px;
margin: 100px auto;
border-radius: 5px;
border: 1px solid #ddd;
`;
const Title = styled.h1`
color: slateblue;
text-align: center;
`;
const Line = styled.hr`
margin: 16px 10px;
border: 2px dotted #ddd;
`;
const ItemStyle = styled.div`
padding: 5px;
margin: 50px 8px 8px 8px;
background-color: #E6E6FA;
line-height: 20px
`;
const Input = styled.div`
max-width: "100%",
min-height: 20vh;
background-color: #E6E6FA;
padding: 10px;
margin: 10px 10px;
display: flex;
& > * {
padding : 10px;
}
& input{
border: 1px solid #888;
width: 100%;
}
& input:focus {
border: 1px solid #a673ff;
outline: none;
}
`;
dic.js
const LOAD = 'dic/LOAD';
const CREATE = "dic/CREATE";
const DELETE = "dic/DELETE";
const UPDATE = "dic/UPDATE";
const AMEND = "dic/AMEND";
// 초기 상태값을 만들어줍니다.
const initialState = {
inputs: [],
};
// 액션 생성 함수예요.
// 액션을 만들어줄 함수죠!
export function loadDic(dic) {
return { type: LOAD, dic };
}
export function createDic(dic) {
return { type: CREATE, dic: dic };
}
export function updateDic(index) {
return { type: UPDATE, index };
}
export function amendDic(amendDic) {
return { type: AMEND, amendDic: amendDic};
}
export function deleteDic(index) {
return { type: DELETE, index };
}
// 리듀서예요.
// 실질적으로 store에 들어가 있는 데이터를 변경하는 곳이죠!
export default function reducer(state = initialState, action = {}) {
switch (action.type) {
case "dic/LOAD":
return state;
case "dic/CREATE": {
const new_dic_list = [...state.inputs, action.dic];
return { inputs: new_dic_list };
}
case "dic/AMEND": {
const new_dic_list = state.inputs.map((dic, idx) => {
if(parseInt(action.amendDic.index) === idx) {
return { ...dic, word:action.amendDic.word,
mean:action.amendDic.mean,
explain:action.amendDic.explain,
example:action.amendDic.example,
same:action.amendDic.same,
completed:action.amendDic.completed};
} else {
return dic
}
})
return { inputs: new_dic_list }
}
case "dic/UPDATE": {
const new_dic_list = state.inputs.map((l, idx) => {
if (parseInt(action.index) === idx) {
if(state.inputs[idx].completed === false) {
return { ...l, completed: true };
} else {
return { ...l, completed: false };
}
} else {
return l
}
})
return { inputs: new_dic_list }
}
case "dic/DELETE": {
const new_dic_list = state.inputs.filter((l, idx) => {
console.log(
parseInt(action.index) !== idx,
parseInt(action.index),
idx
)
return parseInt(action.index) !== idx;
// [1,2,3]에서 2를 빼고 싶으면 2만 빼는게 아니라 [1,3]의 값으로 재반환!
// return은 true와 false로 줄 수 있는데 ture면 현재요소가 들어가고 false면
// 새배열에 이 요소가 들어가지 않는다. true면 값이 들어가는데 false라서 안들어간데!
});
return { inputs: new_dic_list };
}
default:
return state;
}
}
configStore.js
//configStore.js
import { createStore, combineReducers } from "redux";
import dic from "./modules/dic";
// root 리듀서를 만들어줍니다.
// 나중에 리듀서를 여러개 만들게 되면 여기에 하나씩 추가해주는 거예요!
const rootReducer = combineReducers({ dic });
// 스토어를 만듭니다.
const store = createStore(rootReducer);
export default store;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from "react-router-dom";
// 우리의 버킷리스트에 리덕스를 주입해줄 프로바이더를 불러옵니다!
import { Provider } from "react-redux";
// 연결할 스토어도 가지고 와요.
import store from "./redux/configStore";
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
'React' 카테고리의 다른 글
ReactElement vs ReactNode vs JSX.Element (0) | 2022.09.05 |
---|---|
React SEO (0) | 2022.08.26 |
React 패키지 설치 (0) | 2022.01.27 |
리액트 3주차 버킷리스트 만들기 연습 2022-01-26 (0) | 2022.01.26 |
리액트 3주차 버킷리스트 만들기 연습 2022-01-25 (0) | 2022.01.25 |