react

GW·2023년 9월 14일
post-thumbnail

useReducer

useContext

전역으로 사용될 Props 를 여러 컴포넌트에서 공유하여 사용할 수 있도록 하는 Hook

  • 예 > 로그인 데이터 , CSS 테마 , 언어셋 등

이런 데이터들을 모든 컴포넌트가 사용하려면 모든 컴포넌트에 동일한 Props 가 전달되어야 함

  • Prop Drilling (Prop 을 모든 하위 컴포넌트들에게 전달해주는 것)

여러 컴포넌트가 Context 를 구독하는 형태

  • Context 를 사용하면 컴포넌트를 재사용하기 어려워 질 수 있음
  • Prop Drilling 을 피하기 위해 Context 를 사용할 목적이라면 컴포넌트 합성을 사용하는것이 가장 좋은 방법일 수 있다 .
    (React Document)

context (공유데이터)를 만들어서 component에게 공유한다.
(실습없이 지나감)

Axios - RESTful API Service

Axios란?

Javascript 환경에서 사용가능한 비동기 통신 방법

jsonplaceholder

jsonplaceholder ajax통신하기

import axios from "axios";
import { useEffect, useState } from "react";

export default function JsonPlaceHolder(){
        //ajax통신 받아오기 react는 useState로 받아옴
    const[posts,setPosts]=useState([])
    const [status,setStatus]=useState(0)

    //componentDidMount 해당
    useEffect(()=>{
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts(response.data)
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 
             
    },[])
        if(status == 404){
            return(
            <div>
                <Buttons/>
                URL이 올바르지 않습니다.
                </div>
            )
        }else{

            return(
                <div>
                    <Buttons/>
                    {
                        posts.map(post => <div key={post.id}>{post.title}</div>)
                    }{/* 반복시키기  */}
                </div>
            )
        }
}
function Buttons(){
    return(
        <div>
            <button>조회</button>
            <button>한건 조회</button>
            <button>등록</button>
            <button>수정</button>
            <button>삭제</button>
        </div>
    )
}

버튼클릭해서 ajax통신 하기

조회하기

import axios from "axios";
import { useEffect, useState } from "react";

export default function JsonPlaceHolder(){
        //ajax통신 받아오기 react는 useState로 받아옴
    const[posts,setPosts]=useState([])
    const [status,setStatus]=useState(0)

    function getAllPosts(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts(response.data)
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 

    }

    //componentDidMount 해당
    // useEffect(()=>{
    //     const readPostUrl="https://jsonplaceholder.typicode.com/posts"
    //     axios.get(readPostUrl)
    //          .then((response)=>{
    //             console.log(response.status)
    //             console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
    //             setPosts(response.data)
    //             setStatus(response.status)
    //          }) 
             
    //          .catch((error)=>{
    //             setPosts([])
    //             setStatus(error.response.status)
    //         }) 
             
    // },[])
        if(status == 404){
            return(
            <div>
                {/* 버튼을 눌렀을때 이벤트 발생하게 하기 */}
                <Buttons getAllPosts={getAllPosts}/> 
                URL이 올바르지 않습니다.
                </div>
            )
        }else{

            return(
                <div>
                    <Buttons getAllPosts={getAllPosts}/>
                    {
                        posts.map(post => <div key={post.id}>{post.title}</div>)
                    }{/* 반복시키기  */}
                </div>
            )
        }
}
function Buttons({getAllPosts}){
    return(
        <div>
            <button onClick={getAllPosts}>조회</button>
            <button>한건 조회</button>
            <button>등록</button>
            <button>수정</button>
            <button>삭제</button>
        </div>
    )
}

한건조회

import axios from "axios";
import { useEffect, useState } from "react";

export default function JsonPlaceHolder(){
        //ajax통신 받아오기 react는 useState로 받아옴
    const[posts,setPosts]=useState([])
    const [status,setStatus]=useState(0)

    function getAllPosts(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts(response.data)
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 

    }
    function getOnePosts(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts/1"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts([response.data])
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 

    }

    //componentDidMount 해당
    // useEffect(()=>{
    //     const readPostUrl="https://jsonplaceholder.typicode.com/posts"
    //     axios.get(readPostUrl)
    //          .then((response)=>{
    //             console.log(response.status)
    //             console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
    //             setPosts(response.data)
    //             setStatus(response.status)
    //          }) 
             
    //          .catch((error)=>{
    //             setPosts([])
    //             setStatus(error.response.status)
    //         }) 
             
    // },[])
        if(status == 404){
            return(
            <div>
                {/* 버튼을 눌렀을때 이벤트 발생하게 하기 */}
                <Buttons getAllPosts={getAllPosts}
                         getOnePosts={getOnePosts}/> 
                URL이 올바르지 않습니다.
                </div>
            )
        }else{

            return(
                <div>
                    <Buttons getAllPosts={getAllPosts}
                             getOnePosts={getOnePosts}/> 
                    {
                        posts.map(post => <div key={post.id}>{post.title}</div>)
                    }{/* 반복시키기  */}
                </div>
            )
        }
}
function Buttons({getAllPosts,getOnePosts}){
    return(
        <div>
            <button onClick={getAllPosts}>조회</button>
            <button onClick={getOnePosts}>한건 조회</button>
            <button>등록</button>
            <button>수정</button>
            <button>삭제</button>
        </div>
    )
}

등록

function addNewPost(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.post(readPostUrl,{
                    title:"둥록합니다.",
                    body:"새로운 글이에요",
                    userId:1
                })

             .then((response)=>{
                //새로운 글 목록을 조회하는 기능 .
                setPosts([...posts, {
                    title:"둥록합니다.",
                    body:"새로운 글이에요",
                    userId:1,
                    id:201
                }])
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([...posts])
                setStatus(error.response.status)
            }) 
    }

interceptor

요청하기 및 에러응답받기 직전에 코드를 개입시키는 방법

import axios from "axios";
import { useEffect, useState } from "react";

export default function JsonPlaceHolder(){
        //ajax통신 받아오기 react는 useState로 받아옴
    const[isLoad,setIsLoad]=useState(false)
    const[posts,setPosts]=useState([])
    const [status,setStatus]=useState(0)

    axios.interceptors.request.use((config)=>{
        console.log(config)
        setIsLoad(true)
        return config
    },(error)=>{
        console.log(error)
        setIsLoad(false)
        return Promise.reject(error) // error를 돌려주기 
    })
    axios.interceptors.response.use((response)=>{
        console.log(response)
        setIsLoad(false)
        return response
    },(error)=>{
        console.log(error)
        setIsLoad(false)
        return Promise.reject(error)
    })

    function getAllPosts(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts(response.data)
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 

    }
    function getOnePosts(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts/1"
        axios.get(readPostUrl)
             .then((response)=>{
                console.log(response.status)
                console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
                setPosts([response.data])
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([])
                setStatus(error.response.status)
            }) 

    }
    function addNewPost(){
        const readPostUrl="https://jsonplaceholder.typicode.com/posts"
        axios.post(readPostUrl,{
                    title:"둥록합니다.",
                    body:"새로운 글이에요",
                    userId:1
                })

             .then((response)=>{
                //새로운 글 목록을 조회하는 기능 .
                setPosts([...posts, {
                    title:"둥록합니다.",
                    body:"새로운 글이에요",
                    userId:1,
                    id:201
                }])
                setStatus(response.status)
             }) 
             
             .catch((error)=>{
                setPosts([...posts])
                setStatus(error.response.status)
            }) 
    }

    //componentDidMount 해당
    // useEffect(()=>{
    //     const readPostUrl="https://jsonplaceholder.typicode.com/posts"
    //     axios.get(readPostUrl)
    //          .then((response)=>{
    //             console.log(response.status)
    //             console.log(response.data) // 성공 Case(요청이 성공했다. 응답도 정상적으로 도착했다)
    //             setPosts(response.data)
    //             setStatus(response.status)
    //          }) 
             
    //          .catch((error)=>{
    //             setPosts([])
    //             setStatus(error.response.status)
    //         }) 
             
    // },[])
        if(status == 404){
            return(
            <div>
                {isLoad?<Spinner/>:<></>}

                {/* 버튼을 눌렀을때 이벤트 발생하게 하기 */}
                <Buttons getAllPosts={getAllPosts}
                         getOnePosts={getOnePosts}
                         addNewPost={addNewPost}/> 
                URL이 올바르지 않습니다.
                </div>
            )
        }else{

            return(
                <div>
                    {isLoad?<Spinner/>:<></>}
                    <Buttons getAllPosts={getAllPosts}
                             getOnePosts={getOnePosts}
                             addNewPost={addNewPost}
                             /> 
                    {
                        posts.map(post => <div key={post.id}>{post.title}</div>)
                    }{/* 반복시키기  */}
                </div>
            )
        } //get,remove 똑같고 put,post 같음
}
function Buttons({getAllPosts,getOnePosts,addNewPost}){
    return(
        <div>
            <button onClick={getAllPosts}>조회</button>
            <button onClick={getOnePosts}>한건 조회</button>
            <button onClick={addNewPost}>등록</button>
            <button>수정</button>
            <button>삭제</button>
        </div>
    )
}

function Spinner(){
    const style={
        display:"flex",
        justifyContent:"center",
        alignItems:"center",
        zIndex:999,
        postion:"fixed",
        top:0,
        left:0,
        right:0,
        bottom:0
    }
    const imgStyle={
        width:"150px"
    }
    return(
        <div style={style}>
            <img style={imgStyle} src="https://img.pikbest.com/png-images/20190918/cartoon-snail-loading-loading-gif-animation_2734139.png!sw800"/>
        </div>
    )
}

Router

SPA (Single Page Application)

  • 하나의 단일 페이지로 Web App 을 구성
  • Native App 과 유사한 UX 를 제공할 수 있다
  • 페이지 내부의 데이터가 변경되면 전체를 Rendering 하지 않고 변경된 부분만 갱신하므로 데이터 트래픽을 감소시킬 수 있다

MPA (Multi Page Application)

  • 여러 개의 페이지로 Web App 을 구성
  • 페이지 마다 비슷하거나 동일한 코드가 중첩되어 나타난다
  • 페이지 내부의 데이터가 변경되면 전체를 갱신해야만 한다

Routing?

  • 출발지에서 목적지까지의 경로를 결정하는 기술
  • 화면에서 화면간의 이동하기 위한 네비게이션 기능
  • 일반적으로 URL 별 페이지를 전환시키는 기능

  • BrowserRouter 밖에 있으면 절때 라우팅을 할 수 없다.

0개의 댓글