리액트의 장점!
- 긴 HTML 단락을 컴포넌트화 하여 호출하면 관리하기 편하고 코드가 간결해진다.
- 이름은 보통 대문자로 시작
- return 값은 가장 크게 <></>로 묶어 주어야함.
Component화 하면 좋은 HTML 단락은?
- 반복출현 하는 코드
- 자주변경 되는 코드
- 다른 페이지를 만들때도 유용
하지만, state 복잡해짐.
다른 func,컴포넌트에서 선언된 변수 참조 하려면 props 를 사용해야 한다.
자식 Component에서 부모 Component의 state를 사용하기 위함
// 부모
function 부모Component(){
let [부모에있는state,setState] = useState('부모로부터');
return(
<>
<자식Component 전송할이름={state명}>
</>
)
}
//자식
function 자식Component(props){
return(
<div>{props.전송할이름}</div>
)
}
부모에서 자식에게 전달할 때 인자는 여러개여도 된다.
그렇게 전달받은 자식에서는 props.전달받은이름 으로 접근하여 사용할 수 있다.
// 부모
function 부모Component(){
let [부모에있는state1,setState1] = useState('부모로부터1');
let [부모에있는state2,setState2] = useState('부모로부터2');
return(
<>
<자식Component 전송할이름1={state1} 전송할이름2={state2}>
</>
)
}
이라면, 기존 방식으로는 다음과 같이 이용할 수 있다
//자식
function 자식Component(props){
return(
<div>{props.전송할이름1}</div>
<div>{props.전송할이름2}</div>
)
}
이를 구조분해하면
//자식
function 자식Component({state1,state2}){
return(
<div>{state1}</div>
<div>{state2}</div>
)
}
ReactDOM.render(
<BrowserRouter>
<Parent>
<Child/>
</Parent>
</BrowserRouter>,
document.getElementById('root')
);
이처럼 Parent 컴포넌트 안에 Child 컴포넌트를 사용했을 때,
children 설정을 하지 않으면 Child 컴포넌트가 보이지 않는다!!
다음과 같이 children을 이용하여야 한다. (다른 이름 X)
//Parent.js
import React, { useState } from 'react'
const Parent = ({children }) => {
const [number, setNumber] = useState(0)
return (
<div>
<p>여기는 부모입니다 : {number}</p>
{children }
</div>
)
}
export default Parent;
//Child.js
import React from 'react'
const Child = ({ number}) => {
return (
<div>
여기는 CHILD
</div>
)
}
export default Child;
이라면, Child 컴포넌트의 '여기는CHILD'가 나타나지 않는다!!!
children 인자를 설정해주어야 한다!!!!
부모Component의 state를 자식Component에서 수정 등을 하기 위함
부모에서 useState로 작성된 변수의변경함수(setState)
를 자식에 props로 전달한다.
const Parent = (props) => {
const [data, setData] = useState("initial");
return (
<>
<div>{data}</div>
<Child setData={setData} />
</>
);
};
const Child = (props) => {
return (
<>
<button onClick={() => props.setData("changed in Child")}>
Change in Chiild
</button>
</>
);
};
상태관리 라이브러리!
props 전송 없이도 모든 컴포넌트가 그 state를 사용할 수 있도록 한다
npm install redux react-redux
//index.js
import { Provider } from 'react-redux';
import { createStore } from 'redux';
let store = createStore( () => {
return[
{id:0, name: '멋진신발', quan:2}
]
})
<Provider store={store}>
<App />
</Provider>
redux에 데이터로 사용하려는 state를 createStore()로 만든다.
createStore()에 콜백함수가 들어가고 만드려는 state의 초기값을 return한다.
Provider에 만든 state를 props처럼 전달한다.
//App.js
import Cart from './Cart.js';
...
<Route path="/cart" element={<Cart />}></Route>
//Cart.js
function Cart(props){
return (
{props.state[0].name}
{/* stateToProps란 함수에서 state란 이름으로 return했으니 */}
)
}
function stateToProps(state){ //여기인자의 state는 Provider에서 인자로 넘긴 store 변수임.
return {
state : state //인자state(리덕스의 store)를 state란 이름으로 return
}
}
export default connect(stateToProps)(Cart);
// stateToProps함수와 Cart.js를 이어준다
redux에서 데이터를 수정하려면
1 . reducer 함수를 만들고 데이터 수정 방법을 정의한다.
reducer(초기값,액션){
return ()
}
액션 : 데이터 수정을 위한 정보를 가진다. dispatch 안의 모든 객체들을 가짐. 주로 type 값 객체(문자열 등) 형태 사용하여 분기 만듦
//index.js
let 초기값 = [{id : 0, name : '멋진신발', quan : 2}];
function reducer(state = 초기값, 액션){
if (액션.type === '수량증가') {
let copy = [...state];
copy[0].quan++;
return copy
} else {
return state
}
}
let store = createStore(reducer);
//Cart.js
<td><button onClick={()=>{ props.dispatch({type: '수량증가'}) }}> + </button></td>
dispatch인자를 type에 '수량증가'로 주면 reducer에서 그에 맞는 조건이 있을 경우 해당 코드가 실행됨!
2 . 수정할 때 dispatch() 함수를 호출하여 reducer 함수에 정의한대로 수정하도록 한다.
const [상태 객체, dispatch 함수] = useReducer(reducer 함수, 초기 상태, 초기 함수)
const [state, dispatch] = useReducer(reducer, initialState);