자식이 부모의 state 를 가져다 쓰고 싶을 때: props
function App (){
let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
return (
<div>
<Modal></Modal>
</div>
)
}
function Modal(){
return (
<div className="modal">
<h4>{ 글제목[0] }</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
위의 코드를 실행시키면 '글제목' 이라는 변수가 define 되지 않았다는 에러 발생
-> 글제목이라는 state 변수는 function App() 에 있지 function Modal() 에 없기 때문
props 를 사용해서 state 전달하기
1. 자식 컴포넌트를 사용하는 곳에 가서 <자식 컴포넌트 작명={state이름} />
(tip: '작명' 은 보통 state이름과 동일한 이름으로 사용한다)
2. 자식 컴포넌트 만드는 function 으로 가서 props 라는 파라미터 등록 후 props.작명 사용
function App (){
let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
return (
<div>
<Modal 글제목={글제목}></Modal>
</div>
)
}
function Modal(props){
return (
<div className="modal">
<h4>{ props.글제목[0] }</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
props 를 전달할 수 있는 조건
컴포넌트의 관계가 부모 -> 자식인 경우 가능
(형제 -> 형제 or 자식->부모의 경우 불가능)
참고 - props 사용 응용
function Modal(props){
return (
<div className="modal" style={{ background : 'skyblue' }}>
<h4>{ props.글제목[0] }</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
모달창에 배경색을 입히고 싶다면 위의 코드처럼 style 을 적용해 모달창의 배경색을 입혀줄 수 있다.
하지만 하늘색 말고 여러 배경색이 필요해진다면 어떻게 해야할까?
function Modal2() { }
function Modal3() { }
이렇게 배경색이 다른 모달함수를 여러 개 만드는 방법도 있지만,
props 로 배경색을 넘겨주면 굳이 같은 함수를 여러 개 만들 필요가 없다!
(color={'orange'}: 자바스크립트 표현식, color='yellow' 문자열)
function App (){
let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
return (
<div>
<Modal color={'orange'} 글제목={글제목}></Modal>
<Modal color='yellow' 글제목={글제목}></Modal>
</div>
)
}
function Modal(props){
return (
<div className="modal" style={{ background : props.color }}>
<h4>{ props.글제목[0] }</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
숙제: 모달창 안에 글수정 버튼 만들고 버튼 누르면 첫 글제목이 '여자코트 추천' 으로 바뀌는 기능 구현
function App (){
let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
return (
<div>
<Modal 글제목변경={글제목변경} 글제목={글제목}></Modal>
</div>
)
}
function Modal(props) {
return (
<div>
<div className='modal'>
<h4>{props.글제목[0]}</h4>
<p>날짜</p>
<p>상세내용</p>
<button onClick={()=>{
let copy = [...props.글제목];
copy[0] = '여자 코트 추천';
props.글제목변경(copy);
}}>글수정</button>
</div>
</div>
)
}
props를 응용한 상세페이지 만들기: 누른 글의 제목이 모달창에 뜨게 하기
현재 상태: 모달창에 인덱스 0번째의 글제목만 뜸
function App (){
let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
return (
<div>
<Modal 글제목변경={글제목변경} 글제목={글제목}></Modal>
</div>
)
}
function Modal(props) {
return (
<div>
<div className='modal'>
<h4>{props.글제목[0]}</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
</div>
)
}
동적 UI 만들기 복습
1. html css 로 미리 디자인
2. 현재 UI 의 상태를 state 로 만들기
3. state 의 종류에 따라 UI 가 어떻게 보일지 작성
1번까지는 구현되어 있으니 현재 UI 상태를 state 로 만들어야 한다.
function App 안에 title 이라는 state 를 만들고 초기 값을 0으로 설정해주었다.
let [title, setTitle] = useState(0);
state 를 만들었으니 이제는 state 에 따라 UI 가 어떻게 보일지 작성해야 한다.
글제목 0번째 인덱스 글을 누름 -> title: 0 -> 글제목[0]
글제목 1번째 인덱스 글을 누름 -> title: 1 -> 글제목[1]
글제목 2번째 인덱스 글을 누름 -> title: 2 -> 글제목[2]
function App (){
let [title, setTitle] = useState(0);
(생략)
{
글제목.map(function(data, i) {
return (
<div className='list' key={i}>
<h4 onClick={()=>{
setModal(!modal);
setTitle(i);
}}>{ 글제목[i] } <span onClick={()=>{
let copy = [...따봉];
copy[i] = copy[i] + 1;
따봉변경(copy)
}}> 👍 </span> { 따봉[i] } </h4>
<p>5월 1일 발행</p>
</div>)
})
}
}
function Modal(props){
return (
<div className="modal">
<h4>{ props.글제목[title] }</h4>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
가장 중요한 것!
state 는 state 를 사용하는 컴포넌트 중 최상위층에 만들어 놓아야 한다
input 1 : 사용자가 입력한 글 다루기
리액트에서 input 태그를 사용할 때는 html 의 input 를 다룰 때와는 다르게 아래와 같은 형식으로 사용해야 한다.
<input></input>
<input />
유저가 input 태그에 무언가를 입력시 코드를 실행시키고 싶다면 아래의 코드와 같이 이벤트 핸들러를 부착하면 된다.
<input onChange={()=>{ 실행할코드 }}/>
- onChange / onInput : 유저가 input 태그에 뭔가를 입력할 때
- onMouseOver : 해당 요소에 마우스를 가져다 대었을 때
- onScroll: 해당 요소에 스크롤이 존재할 때 스크롤을 했을 때
이 외에도 다양하고 많은 핸들러가 존재하니 필요한 이벤트 핸드러를 찾아서 사용하면 된다.
input 태그에 어떤 값이 입력되었고, 입력된 값을 사용하고 싶다면 e 라는 파라미터를 사용하면 된다. 이 파라미 발생하는 이벤트와 관련된 여러 기능들을 가지고 있는 파라미터로 아래와 같이 사용할 수 있다.
(통상적으로 e 라는 이름으로 불리지만, 다른 이름으로 사용해도 상관없다)
<input onChange={(e)=>{ console.log(e.target.value) }}/>
- e. target: 현재 이벤트가 발생한 곳을 알려줌
- e.target.value: 태그에 입력된 값을 알려줌
- e.preventDefault: 이벤트 기본 동작을 막아줌
- e.stopPropagation: 이벤트버블링 막기
<div><h4><span onClick={()=>{ }}></span></h4></div>
위 코드와 같은 구조를 가지고 있을 때 span 태그를 누르면 총 3번 클릭한 것처럼 동작하는데, 이처럼 이벤트가 상위 요소로 퍼지는 현상을 이벤트버블링이라고 한다.
이벤트버블링은 원치 않는 결과를 불러올 수 있는데 이때 e 파라미터를 사용 e.stopPropagation() 을 사용하면 이벤트버블링을 막을 수 있다.
사용자가 input 에 입력한 데이터 저장하기
사용자가 input 에 입력한 데이터는 state 또는 변수에 저장해서 쓰는 것이 일반적이다.
function App (){
let [입력값, 입력값변경] = useState('');
return (
<input onChange={(e)=>{
입력값변경(e.target.value)
console.log(입력값)
}} />
)
}
참고 - state 변경함수는 비동기함수
위의 코드에서 input 태그에 a 한 글자를 입력하면 아무 것도 콘솔창에 출력되지 않고, 두 글자 이상 입력 시 출력이 잘 되는 현상이 나타난다. 이는 입력값변경이라는 state 변경함수가 늦게 처리되기 때문인데, 자바스크립트는 state 변경함수와 같이 늦게 처리되는 비동기함수는 제쳐두고 다음 줄부터 실행하려는 특성이 있기 때문이다.
그래서 입력값변경(e.target.value) 가 실행되고 완료되기 전에 console.log(입력값) 이 실행되어 글자가 한 개 일때는 출력되지 않고 두 개 이상일 때부터 출력이 잘 되는 것이다.
숙제:
1. 글발행 버튼을 만들고 버튼을 눌렀을 때 input 에 입력한 값을 제목으로 하는 글 발행
2. 글마다 삭제버튼을 만들고 삭제 버튼을 누르면 글 삭제
글 발행버튼 구현
function App (){
let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
let [입력값, 입력값변경] = useState('');
return (
<div>
<input onChange={ (e)=>{ 입력값변경(e.target.value) } } />
<button onClick={()=>{
let copy = [...글제목];
copy.unshift(입력값);
글제목변경(copy)
}}>글발행</button>
</div>
)
}
- unshift : array 맨 앞에 자료를 추가
글 삭제버튼 구현
function App (){
let [글제목, 글제목변경] = useState(['남자코트추천', '강남우동맛집', '파이썬독학']);
let [입력값, 입력값변경] = useState('');
return (
<div>
{
글제목.map(function(a, i){
return (
<div className="list">
<h4>{ 글제목[i] }</h4>
<p>2월 18일 발행</p>
<button onClick={()=>{
let copy = [...글제목];
copy.splice(i, 1);
글제목변경(copy);
}}>삭제</button>
</div>
)
})
}
</div>
)
}
- splice(index, n) : index 부터 n 개의 요소 삭제
'웹 > 24-StudyWithPnP' 카테고리의 다른 글
[React+JS/리액트] 웹 스터디 8주차 (0) | 2024.06.12 |
---|---|
[React+JS/리액트] 웹 스터디 7주차 (0) | 2024.06.05 |
[React+JS/리액트] 웹 스터디 6주차 (2) | 2024.06.03 |
[React+JS/리액트] 웹 스터디 5주차 (0) | 2024.05.23 |
[React+JS/리액트] 웹 스터디 4주차 (0) | 2024.05.16 |