FrontEnd 개발에는 ES6를 제대로 알아야한다.
현재 FrontEnd에는 정말 다양한 라이브러리와 프레임워크가 존재한다. 그 중에 대표적으로 React, Vue, Angular를 꼽을 수 있다.
물론 이 세가지 라이브러리 혹은 프레임워크들이 프론트엔드에서 계속 살아남을것이라는 보장은 할 수 없을 것이다. 프론트엔드의 대표 셋도 정말 다양하게 변화하고 있는 실정이다. 그래서 어떤 기술을 사용하더라도 꼭 알아야하는 것이 바로 자바스크립트 ES6이다.
현재 내가 프론트엔드에서 사용하는 기술은 React이지만 어떤 기술을 사용하든 ES6문법을 제대로 활용할 수 있다면 제목에 있는 사진, 파일업로드는 어디서든 사용할 수 있을 것이라 생각된다.
html 코드
<form onSubmit={onSubmit}>
<input
value={kweet}
type="text"
placeholder={"What's on your mind?"}
maxLength={120}
onChange={onChange}
/>
<input type="file" accept={"image/*"} onChange={onFileChange}/>
<input type="submit" value={"Kweet"} />
{image && (
<div>
<img src={image} alt="img" width={"50px"} height={"50px"}/>
<button onClick={onClearPhotoClick}>취소</button>
</div>
)}
</form>
html 9번째 줄에 있는 onChange는 input태그에 변화가 있을 때 onFileChange라는 function을 작동시킨다.
위와 같이 input태그의 타입을 file로 바꾸고 accept에 image/*를 통해 이미지가 전달되는 input태그를 만들어준다.
Javascript 코드
const onFileChange = (e) => {
const {
target : {files},
} = e;
const theFile = files[0];
const reader = new FileReader();
reader.readAsDataURL(theFile);
reader.onloadend = (finishedEvent) =>{
const {currentTarget : { result }} = finishedEvent;
setImage(result);
}
}
이후에 JS코드에서 발생한 이벤트에서 files를 찾아낸다. 여기서 주의해야할점은 files로 바로 받는게 아니라 files[0]로 받아야 한다는 점이다. files는 배열로 들어오기 때문에 그중에 0번째에 저장되어있는 파일을 받아야한다.
FileReader 메소드들은 MDN을 읽어보면 자세히 나와있다.
const [image, setImage] = useState("")
FileReader를 통해 URL을 읽고 state 관리를 위해 만들어 놓은 setImage에 결과값을 저장하면 된다.
위 코드는 노마드에서 나온 코드를 활용한 것이고 실제 프로젝트에서는 아래와 같은 코드로 image업로드 component를 작성했다.
팀프로젝트에서 사용한 코드
import React, {useState} from 'react';
import http from "./http";
import FittedImage from "react-fitted-image";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
const imageReducer = ( state={}, action ) => {
switch (action.type) {
default: return state
}
}
export const Image = ({path, setImgLink}) => {
const[content, setContent] = useState(undefined)
const[img, setImg] = useState(undefined)
const[url, setUrl] = useState('')
const[formData] = useState(new FormData())
const addFile = (e) => {
setContent(e.target.files[0]);
setUrl(URL.createObjectURL(e.target.files[0]))
};
const uploadService = file => {
formData.append("file", file)
return http.post(`/${path}`, formData, {})
}
const upload = (e) => {
e.preventDefault()
if(url !== ''){
let currentFile = content
setImg(currentFile)
uploadService(currentFile)
.then((res)=>{
alert(`파일이 업로드되었습니다. imgLink : ${res.data}`)
setImgLink(res.data)
setContent(undefined)
setImg(undefined)
setUrl('')
})
.catch(()=>{
setImg(undefined)
setContent(undefined)
setUrl('')
window.location.reload()
alert('파일업로드 실패')
})
}else{
alert("파일을 선택해주세요")
}
}
const cancel = (e) => {
e.preventDefault()
setImg(undefined)
setContent(undefined)
setUrl('')
window.location.reload()
}
return (
<>
{url ? (
<>
<div className="input-air-primary">
<b>미리보기</b>
<FittedImage fit="contain" src={url} alt="#" />
</div>
</>
) : (
""
)}
<Container className="input-air-success">
<Row>
<Col/>
<Col>
<input type="file" onChange={addFile} />
</Col>
<Col/>
</Row>
<Row>
<Col/>
<Col>
<button className="btn btn-outline-primary" type="button" onClick={upload}>업로드</button>
</Col>
<Col>
<button className="btn btn-outline-danger" onClick={cancel}>취소</button>
</Col>
<Col/>
</Row>
</Container>
</>
)
}
export default imageReducer
두가지 코드를 보며 느낀점
비슷하면서도 다른 코드인데 ES6를 좀더 공부하고 했다면 프로젝트에서 하드코딩이 줄어들지 않았을까 생각이든다. 노마드를 통해서 공부하면서 FrontEnd 개발자가 되고자한다면 ES6문법에 집중해야겠다는 생각이 들었다.