**CSR - 클라이언트 사이드 랜더링: 서버와 클라이언트 애플리케이션을 따로 구현
1.node 기반의 프로젝트를 clone 한 후 사용하는 방법
1) git에서 clone
2)필요한 패키지 설치
npm install
*강제 설치
npm install --save --legacy-peer-deps@material-ui/core
npm install --save --legacy-peer-deps@material-ui/icons
3)실행
yarn start
2.삭제 구현
1) 삭제 아이콘 구현
=>mui.com활용
https://mui.com/material-ui/material-icons/
import React from "react"
import {
ListItem,
ListItemText,
InputBase,
Checkbox,
ListItemSecondaryAction,
IconButton
} from "@material-ui/core"
import DeleteOutlined from "@material-ui/icons/DeleteOutlined"
//react 에서 컴포넌트 클래스를 만들기 위해 Component로부터 상속받기
class ToDo extends React.Component {
//생성자
constructor(props){
super(props); //상위 클래스에서 넘겨준 모든 props를 현재클래스에 저장
//state 생성
//item 이라는 이름으로 props 중에서 item 이라는 값을 state로 저장
//props은 상위 component 에서 전달한 data라 읽기만 가능
//수정이나 삭제를 하고자 하는 경우는 state 로 변환해야함.
this.state={item:props.item}
}
//화면에 출력할 내용을 리턴하는 메서드
//props는 수정이 안되서 state로 변환
render(){
//자주 사용하는 데이터를 짧게 사용하기 위해서 다른 변수에 대입
const item=this.state.item;
return(
<ListItem>
<Checkbox checked={item.done}/>
<ListItemText>
<InputBase
inputProps={{"aria-label":"naked"}}
type="text"
id={item.id}
name={item.id}
value={item.title}
multiline={true}
fullWidth={true}
/>
</ListItemText>
<ListItemSecondaryAction>
<IconButton aria-label="Delete ToDo">
<DeleteOutlined />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)
}
}
2)삭제를 처리할 메서드를 App.js 파일에 생성
//삭제를 위한 메서드
delete=(item)=>{
//state나 props 의 데이는 직접 편집이 안됩니다.
const thisItems=this.state.items;
//복사본에서 item을 제거
//filter함수는 return type이 boolean 함수를 매개변수로 받아서
//리턴결과 true인 데이터만 모아서 배열로 리턴하는 함수입니다.
const newItems = thisItems.filter((e)=>e.id !== item.id);
//원본에 다시 복사
this.setState({items:newItems})
}
3)ToDo.jsx에 삭제할 메서드 연결후 이벤트처리기
import React from "react"
import {
ListItem,
ListItemText,
InputBase,
Checkbox,
ListItemSecondaryAction,
IconButton
} from "@material-ui/core"
import DeleteOutlined from "@material-ui/icons/DeleteOutlined"
//react 에서 컴포넌트 클래스를 만들기 위해 Component로부터 상속받기
class ToDo extends React.Component {
//생성자
constructor(props){
super(props); //상위 클래스에서 넘겨준 모든 props를 현재클래스에 저장
//state 생성
//item 이라는 이름으로 props 중에서 item 이라는 값을 state로 저장
//props은 상위 component 에서 전달한 data라 읽기만 가능
//수정이나 삭제를 하고자 하는 경우는 state 로 변환해야함.
this.state={item:props.item}
//App.js에서 넘겨준 삭제 함수를 현재 클래스의 데이터로 변환
this.delete = this.props.delete //부모가 넘겨준함수는 this.delete로 변환
}
//화면에 출력할 내용을 리턴하는 메서드
//props는 수정이 안되서 state로 변환
//삭제 버튼 누를 떄 호출될 이벤트 핸들러
deleteEventHandler=(e)=>{
this.delete(this.state.item)
}
render(){
//자주 사용하는 데이터를 짧게 사용하기 위해서 다른 변수에 대입
const item=this.state.item;
return(
<ListItem>
<Checkbox checked={item.done}/>
<ListItemText>
<InputBase
inputProps={{"aria-label":"naked"}}
type="text"
id={item.id}
name={item.id}
value={item.title}
multiline={true}
fullWidth={true}
/>
</ListItemText>
<ListItemSecondaryAction>
<IconButton aria-label="Delete ToDo" onClick={(this.deleteEventHandler)}>
<DeleteOutlined />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)
}
}
export default ToDo;
이제 여기에 입력,삭제가 가능해집니다!
3.CORS
1)서버 애플리케이션 구동
예전에 만든 ToDo/Backend 구현
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
2)클라이언트 애플리케이션의 App.js 파일에 데이터를 요청하는 코드를 App 클래스 안에 추가
//화면이 보여질때마다 호출되는 수명주기 함수
//화면이 보여질때마다 호출되는 수명주기 함수
componentDidMount(){
//ajax 요청 개체 생성
let request = new XMLHttpRequest();
//요청 준비
request.open('GET',"http://127.0.0.1/todo/?userid=adam");
//요청
request.send('');
//응답 처리
request.addEventListener('load',()=>{
//json 데이터 출력
conseole.log(request.responseText)
})
=>클라이언트 애플리케이션을 구동하면
=>브라우저에서 http://localhost:3000. 로 접속한 후 검사 창을 확인
CORS POLICY 에러가 출력됩니다
=>SOP(동일 출처 정책)
ajax나 fetch api는 브라우저의 동일 출처 정책에 따라 자신과 동일한 도메인의 데이터만 받아 올 수 있습니다.
동일 도메인이라는 것은 IP 주소와 포트번호까지를 의미합니다.
서버 애플리케이션과 클라이언트 애플리케이션을 따로 구현하면 SOP 정책에 따라 ajax나 fetch api를 이용해서는 서버의 데이터를 사용할 수 없습니다.
서버 애플리케이션은 127.0.0.1:80 구동중이고 클라잉너트 애플리케이션은 localhost(127.0.0.1):3000으로 구종중이라 데이터를 가져올 수 없습니다.
=>해결책
서버 애플리케이션에서 요청이 가능한 클라이언트 애플리케이션의 도메인을 등록해주어야 합니다.
서버 애플리케이션을 만들 때 CORS 설정을 확인해 두어야 합니다.
react의 경우는 react의 설정 파일에 설정을 해도 CORS 설정이 가능합니다.
이유는 react가 node.js플랫폼 위에서 동작을 하는데 node.js는 C/C++이라서 proxy 를 이용해서 react에 데이터를 넘겨줄 수 있습니다.
3)django의 CORS 설정
=>cors 관련 라이브러리 설치: pip install django-cors-headers
=>django 프로젝트의 settings.py파일에 애플리케이션을 등록
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"todoapplication",
"corsheaders"
]
=>django 프로젝트의 settings.py파일에 corsheaders.middleware.CorsMisddleware 애플리케이션을 Middleware 맨앞에 등록
MIDDLEWARE = [
"corsheaders.middleware.CorsMisddleware"
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
=>django 프로젝트의settings.py 파일에 허용할 List 등록
#허용할 도메인을 등록
#실제로는 배포하는 도메인을 등록
CORS_ORIGIN_WHITELIST=['http://127.0.0.1:3000','http://localhost:3000']
CORS_ORIGIN_CREDENTIALS=True
=>서버를 재구동
'Study > FrontEnd' 카테고리의 다른 글
JavaScript(4) (0) | 2024.04.23 |
---|---|
JavaScript(3) (1) | 2024.04.18 |
React(2)-이벤트 처리기 (1) | 2024.01.30 |
React(1)- Django + React.js Application (1) | 2024.01.30 |
FrontEnd (0) | 2024.01.18 |