Context API
여러개의 컴포넌트를 거쳐서 전달할 때 사용하면 복잡한 구조를 해결 할 수 있습니다.
Context 기본문법
// 내보내주기
export const UserDispatch = React.createContext(null);
// 사용때 불러오기
import { UserDispatch } from './App';
// createContext의 파라미터에 Context의 기본값을 설정할 수 있으며,
// 값을 따로 지정하지 않을 경우 사용되는 기본 값
const UserDispatch = React.createContext(null);
// Context를 생성하면, Context 안에 Provider라는 컴포넌트가 들어가있음
// 이 컴포넌트를 통하여 Context의 값을 정할 수 있으며, value 라는 값 설정
<UserDispatch.provider value={dispatch}>...</UserDispatch.Provider>
UserList.js
import React,{useContext} from 'react';
import {UserDispatch} from "./App";
const User = React.memo(function User({user}) {
const dispatch = useContext(UserDispatch);
return(
<>
<p>
<b onClick={() => {dispatch({type:'TOGGLE_USER', id:user.id});}} style={{cursor:'pointer', color: user.active ? 'green' : 'black'}}>{user.username}</b>"{user.email}"
<button onClick={() => {dispatch({type:'REMOVE_USER', id: user.id});}} type="button">삭제</button>
</p>
{user.username}
</>
)
});
function UserList({users}) {
return (
<>
{users.map(user => (
<User user={user} key={user.id} />
))}
</>
)
}
export default React.memo(UserList);
CreateUser.js
import React, {useContext, useRef} from 'react';
import {UserDispatch} from "./App";
import useInputs from "./hooks/useInputs";
const CreateUser = () => {
const [{ username, email }, onChange, reset] = useInputs({
username: '',
email: ''
});
const nextId = useRef(4);
const dispatch = useContext(UserDispatch);
const onCreate = () => {
dispatch({
type: 'CREATE_USER',
user: {
id: nextId.current,
username,
email
}
});
reset();
nextId.current += 1;
}
return (
<>
<input name="username" onChange={onChange} value={username} placeholder="계정명" type="text"/>
<input name="email" onChange={onChange} value={email} placeholder="계정명" type="text"/>
<button onClick={onCreate} type="submit">등록</button>
</>
)
}
export default React.memo(CreateUser);
App.js
import React, { useRef, useReducer, useMemo, useCallback } from 'react';
import Inner from "./Inner";
import UserList from './UserList';
import CreateUser from './CreateUser';
import useInputs from './hooks/useInputs';
function countActiveUsers(users) {
console.log('활성 사용자 수를 세는중...');
return users.filter(user => user.active).length;
}
const initialState = {
users: [
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
},
{
id: 2,
username: 'tester',
email: 'tester@example.com',
active: false
},
{
id: 3,
username: 'liz',
email: 'liz@example.com',
active: false
}
]
};
function reducer(state, action) {
switch (action.type) {
case 'CREATE_USER':
return {
users: state.users.concat(action.user)
};
case 'TOGGLE_USER':
return {
...state,
users: state.users.map(user =>
user.id === action.id ? { ...user, active: !user.active } : user
)
};
case 'REMOVE_USER':
return {
...state,
users: state.users.filter(user => user.id !== action.id)
};
default:
return state;
}
}
// UserDispatch 라는 이름으로 내보내줌
export const UserDispatch = React.createContext(null);
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
const { users } = state;
const count = useMemo(() => countActiveUsers(users), [users]);
return (
<UserDispatch.Provider value={dispatch}>
<React.Fragment>
<Inner>
<CreateUser />
<UserList users={users} />
<p>활성사용자 수 : {count}</p>
</Inner>
</React.Fragment>
</UserDispatch.Provider>
);
}
export default App;
'Web Tech > react' 카테고리의 다른 글
React 기본 - 2.리액트 환경설정 및 시작하기 (0) | 2022.01.11 |
---|---|
React 기본 - 1.리액트란? (0) | 2022.01.11 |
react 기본 - 17.커스텀 Hooks (0) | 2021.12.06 |
react 기본 - 16.useReducer (0) | 2021.11.30 |
react 기본 - 15.React.memo (0) | 2021.11.30 |