본문 바로가기

프론트앤드 수업

[React] Constext 활용

728x90

context API

props는 하나하나를 타고 이동해야하지만 context는 바로 그 내용을 불러올 수 있다.

프로젝트 안에서 전역적으로 사용할 수 있는 값을 관리
createContext(null); => context를 리턴 -> 컴포넌트
const MyContext = createContext(null);
나중에 value로 값을 넣기에 null을 넣음.

  1. 컨텍스트 만들기
    const MyContext = createContext(기본값)

App 최상단으로가서 감싸준다.
<MyContext.Provider value={user}> 보내주고 싶은 값을 넣어준다.



</MyContext.Provider>

  1. 컨텍스트 값 사용하기
    import React, { useContext } from 'react';
    import { MyContext } from '../component/MyContext';
    값을 불러오고 사용하는 선언도 함께 해줘야함.(하위 컴포넌트에서)
    const user = useContext(MyContext)

중간단계를 건너뛰기 떄문에 계속 거치지않고 바로 값을 받아올 수 있다.

완성사진 입력되어있는 reducer값으로 값을 넣어준다.

2022년도를 누를시 2022년도만 표출되도록 되어있으며 삭제를 누를시 해당 글은 삭제된다.

BookConstext.js

import React,{createContext, useContext, useReducer} from 'react';

// 객체배열로 원본배열보존을 위해 따로 필터리스트를 만들어줌.
// 만들지 않을시 한번 검색 후 나머지 배열이 다 사라져있음.
const initialLists = {
    total: [
        {id:1, writer:"공유",title:"나는 나로 살기로 했다.",year:"2022"},
        {id:2, writer:"전지현",title:"경이로운 소문",year:"2022"},
        {id:3, writer:"손예진",title:"UI/UX 디자인 이론과 실습",year:"2022"},
        {id:4, writer:"현빈",title:"만들면서 배우는 제이쿼리",year:"2022"},
        {id:5, writer:"공유",title:"이상한 나라의 엘리스",year:"2021"},
        {id:6, writer:"신채경",title:"인어공주",year:"2021"},
        {id:7, writer:"유진",title:"일러스트레이터 강의",year:"2021"},
        {id:8, writer:"박소담",title:"인터렉티브 웹디자인",year:"2020"},
        {id:9, writer:"정우성",title:"코어 자바스크립트",year:"2020"},
        {id:10, writer:"이정재",title:"기초부터 배우는 html css",year:"2020"},
        {id:11, writer:"한가인",title:"디자이너의 포토샵 스킬북",year:"2019"},
        {id:12, writer:"이유리",title:"인디자인 프로",year:"2019"},
        {id:13, writer:"김태희",title:"좋은사람에게만 좋은 사람이고 싶다.",year:"2019"},
        {id:14, writer:"케이윌",title:"내일죽고 싶지만 떡볶이는 먹고싶어",year:"2019"}
    ],
    filterList: [
        {id:1, writer:"공유",title:"나는 나로 살기로 했다.",year:"2022"},
        {id:2, writer:"전지현",title:"경이로운 소문",year:"2022"},
        {id:3, writer:"손예진",title:"UI/UX 디자인 이론과 실습",year:"2022"},
        {id:4, writer:"현빈",title:"만들면서 배우는 제이쿼리",year:"2022"},
        {id:5, writer:"공유",title:"이상한 나라의 엘리스",year:"2021"},
        {id:6, writer:"신채경",title:"인어공주",year:"2021"},
        {id:7, writer:"유진",title:"일러스트레이터 강의",year:"2021"},
        {id:8, writer:"박소담",title:"인터렉티브 웹디자인",year:"2020"},
        {id:9, writer:"정우성",title:"코어 자바스크립트",year:"2020"},
        {id:10, writer:"이정재",title:"기초부터 배우는 html css",year:"2020"},
        {id:11, writer:"한가인",title:"디자이너의 포토샵 스킬북",year:"2019"},
        {id:12, writer:"이유리",title:"인디자인 프로",year:"2019"},
        {id:13, writer:"김태희",title:"좋은사람에게만 좋은 사람이고 싶다.",year:"2019"},
        {id:14, writer:"케이윌",title:"내일죽고 싶지만 떡볶이는 먹고싶어",year:"2019"}
    ] 
}


function bookReducer(state, action){
    switch(action.type){
        case "YEAR_LISTS":
        return {   // 연도별 검색기능
            ...state, // 객체배열을 모두 펼쳐준다.
            filterList: state.total.filter(list=>list.year === action.year)
        }        // 펼친후 filter를 이용해 클릭된 연도와 total에 있는 연도를 비교해 해당 연도만 가져오도록 한다.
        case "TOTAL_LISTS":
        return state; 
        case "DELETE_LIST": // 삭제 기능
        return { // total과 filterList 모두 삭제하기위해 두가지를 모두 id를 기준으로 잡아 필터로 해당 id와 다른것만 출력하도록 한다.
            total:state.total.filter(list=>list.id !== action.id),
            filterList:state.filterList.filter(list=>list.id !== action.id)
        }
        default:
        return state;
    }
}
const BookListContext = createContext(); // 어디서든 불러올 수 있도록 Context 생성
const BookDispatchContext = createContext();
export function BookProvider({children}){
    const [state, dispatch] = useReducer(bookReducer, initialLists); // useReducer를 선언해 변수에 넣어준다.
    return (
        <BookListContext.Provider value={state}>
            <BookDispatchContext.Provider value={dispatch}>    
                {children}
            </BookDispatchContext.Provider>
        </BookListContext.Provider>
    )// BookListContext, BookDispatchContext에 값을 넣어서 어디서든 사용가능하도록 만듬.
}
// 사용을 쉽게 하기 위해 함수에 넣어 함수만사용하도록 미리 함수선언
export function useBookList(){
    return useContext(BookListContext);
}
export function useBookDispatch(){
    return useContext(BookDispatchContext);
}

App.js

function App() {
  return (
    // context로 선언한내용을 제일 윗단으로 감싸줌(모든 자식객체에 사용가능)
    <BookProvider>
    <div className="App">
        <ContainerDiv>
          <Header />
          <Content />
        </ContainerDiv>
    </div>
    </BookProvider>
  );
}

contents.js
Constext로 값을 가져와 값을 넣어줌

import ContentList from './ContentList';
import { useBookList,useBookDispatch } from '../context/BookContext';
const Content = () => { 
    const { filterList } = useBookList(); // BookContext 제일 아래에 있던 함수를 불러와 fillterList로 객체를 생성
    const dispatch = useBookDispatch(); // dispatch구문을 사용하기위해 마찬가지로 함수호출

    return (
        <div className='content'>
            <table>
                <tr>
                    <th>글쓴이</th>
                    <th>제목</th>
                    <th>년도</th>
                </tr>
                {filterList.map(list=><ContentList list={list} key={list.id} dispatch={dispatch}/>)}
                        //ContentList로 값을 보내준다.
            </table>
        </div>

ContentList

const ContentList = ({ list, dispatch}) => {
    const onDelete = ()=>dispatch({ // map으로 돌려 list값을 가져와 delete구문 생성
        type: 'DELETE_LIST',
        id: list.id // 구분을위해 id값만 보내서 클릭시 해당 글 삭제
    })
    return (
        <tr>
            <td>{list.writer}</td>
            <td>{list.title}</td>
            <td>{list.year}<button onClick={onDelete}>삭제</button></td>
        </tr>
    );
};
728x90
댓글