Intro
์ด๋ฒ์ ๊ณตํต ์ปดํฌ๋ํธ๋ฅผ ๊ตฌํํ๊ณ ์ ๋ฐ์ ์ธ ์คํ์ผ๋ง์ ์ฃผ๋ก ์งํํ๋ค.
8์ผ์ ํ๋ก์ ํธ ์ค๊ฐ ์ ๊ฒ์ด ์์ด์ ์ค๊ฐ ๋ณด๊ณ ์๋ ์์ฑ์ ํ๊ณ ์ง๊ธ๊น์ง ์ง ์ฝ๋๋ค์ ๋ฉํ ๋๊ป ์ฝ๋๋ฆฌ๋ทฐ๋ ๋ฐ์๋ค.
ํ๋ก์ ํธ ์งํ ์ฌํญ
๊ณตํต ์ปดํฌ๋ํธ ์ธํ
๋ณธ ํ๋ก์ ํธ์์ ํ์ด์ง๊ฐ ํ ํ์ด์ง์ด๊ธด ํ์ง๋ง ์ถํ ํ์ฅ๋ ์ ์๊ธฐ ๋๋ฌธ์.. ๊ณตํต ์ปดํฌ๋ํธ์ธ Header, Footer, CustomButton์ ๊ตฌํํ๋ค.
- App.css
/* HEADER */
.header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ececec;
margin-bottom: 24px;
width: 100%;
background-color: #fff;
position: sticky;
top: 0;
z-index: 3;
}
Header๋ position: sticky๋ฅผ ์ด์ฉํด ์คํฌ๋กค์ ๋ด๋ ค๋ ์๋จ์ ์ ์ง๋๋๋ก ๊ตฌํํ์๋ค.
๋ฒํผ ์ปดํฌ๋ํธ๋ MUI ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
React Button component - Material UI
Buttons allow users to take actions, and make choices, with a single tap.
mui.com
๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋นํด ๊น๋ํ ๋์์ธ์ด ๋ง์์ ๋ค์๋ค.
state context ์ค์ ํ๊ธฐ
๋น๋์ค ํ์ผ๊ณผ ๋น๋์ค ํ์ผ์ ์ถ๊ฐํ๊ณ ์ญ์ ํ๋ ํจ์๋ ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ์ฌ์ฉ๋ ๊ฑฐ๋ผ context๋ก ๊ด๋ฆฌํ๊ธฐ๋ก ํ์๋ค.
- App.js
import React, { useReducer } from 'react';
import './App.css';
import Header from './components/Header';
import Footer from './components/Footer';
import VideoEditorMain from './components/VideoEditorMain';
const reducer = (state, action) => {
switch (action.type) {
case 'ADD_FILE':
return action.newItem;
case 'DELETE_FILE':
return null;
default:
return state;
}
};
export const VideoFileContext = React.createContext();
export const VideoFileDispatchContext = React.createContext();
function App() {
const [videoFile, dispatch] = useReducer(reducer, null);
const addFile = file => {
dispatch({ type: 'ADD_FILE', newItem: file });
};
const deleteFile = () => {
dispatch({ type: 'DELETE_FILE' });
};
return (
<VideoFileContext.Provider value={videoFile}>
<VideoFileDispatchContext.Provider value={{ addFile, deleteFile }}>
<div className="App">
<Header></Header>
<VideoEditorMain></VideoEditorMain>
<Footer></Footer>
</div>
</VideoFileDispatchContext.Provider>
</VideoFileContext.Provider>
);
}
export default App;
๋ฆฌ์กํธ Context๋ก ๋น๋์ค ํ์ผ ๋ฐ์ดํฐ์ dispatch ํจ์๋ฅผ ๋ชจ๋ ์ปดํฌ๋ํธ์ ์ ๊ณตํ์๋ค.
๋น๋์ค ์ ๋ก๋ UI ๊ตฌํ
๋น๋์ค๋ฅผ ์ ๋ก๋ํ๋ ์ปดํฌ๋ํธ๋ฅผ input[type=file] ์์๋ก ๊ตฌํํ์๋ค.
์ฒ์์๋ ์ด๋ฏธ์ง๋ฅผ ํด๋ฆญํ๋ฉด useRef๋ก input ์์๋ฅผ ํด๋ฆญํ๋๋ก ๊ตฌํํ๋๋ฐ ๊ตณ์ด ๊ทธ๋ด ํ์๊ฐ ์๋ค๋ ๊ฒ์ ์ฝ๋๋ฆฌ๋ทฐ๋ฅผ ํตํด ์๊ฒ ๋์๋ค.
- VideoPlaceholder.js
import React from 'react';
import video_placeholder from '../assets/video_placeholder.png';
const VideoPlaceholder = ({ onChange }) => {
return (
<section className={'upload-layout'}>
<label>
<img
className={'video-upload-img'}
src={video_placeholder}
alt="๋น๋์ค๋ฅผ ์
๋ก๋ํด์ฃผ์ธ์"
/>
<input
className={'video-upload-input'}
type="file"
accept="video/*"
onChange={e => {
onChange(e.target.files[0]);
}}
/>
</label>
</section>
);
};
export default VideoPlaceholder;
๋ผ๋ฒจ๋ก img ํ๊ทธ๋ฅผ ๊ฐ์ธ์ ์ด๋ฏธ์ง๋ฅผ ํด๋ฆญํ์ ๋ ํ์ผ ์ ํ์ด ๊ฐ๋ฅํ๋๋ก ์ฝ๋๋ฅผ ์์ ํ๋ค.

๋ง๋ฌด๋ฆฌ
ํ๋ก์ ํธ๋ฅผ ํ๋๊น ์๊ฐ์ด ๋น ๋ฅด๊ฒ ํ๋ฌ๊ฐ๋ค.
์์ง๋ ๊ตฌํํด์ผ ํ ๊ฒ ๋ง์ด ๋จ์๋๋ฐ ์๊ฐ ๋ด์ ๊ตฌํํ ์ ์์๊น..