state
: 내부에서 변화하는 값이다. 리액트 컴포넌트는 state가 변경되면 리렌더링을 한다! 컴포넌트 안에서 구조분해 할당으로 초기화하고,const [nowstate, setstate] = uesState(초깃값)
state 변수는 함수가 끝나도 사라지지 않는다.
props
: 외부(부모, 상위 컴포넌트)로부터 전달받은 값이다. 객체형태로 전달되어 어떤 형태의 값을 넣어도 전달할 수 있다. 읽기전용으로 변하지 않는 값이기도 하다.
import { useState } from "react"; // 상단에 넣어준다. function App() { const [showPopup, setShowPopup] = useState(false);
이렇게
showPopup(현재상태//false)
,setShowPopup(변경상태)
를 정의하고useState(초깃값)
으로 초깃값을false
로 초기화해 준다.const togglePopup = (event) => { setShowPopup(event.target); };
현재상태를 바꿀 수 있는 함수이다. 함수를 부른
event
가 행해졌을 때,setShowPopup
에event.target
을 저장해showPopup(현재상태)
를 변경해 준다. 이때,showPopup
을 바꿀 수 있는 것은setShowPopup
뿐임을 명심하자!return ( <div className="App"> <h1>Fix me to open Pop Up</h1> <button className="open" onClick={togglePopup}>Open me</button> {showPopup ? ( <div className="popup"> <div className="popup_inner"> <h2>Success!</h2> <button className="close" onClick={()=> setShowPopup(false)}> // 클릭 시 안의 팝업을 닫음 Close me</button> </div> </div> ) : null} // 클릭 시 안의 팝업을 열고, 아니면 보여주지 않음 </div> ); }
이 때 중요한 것은
onClick
,onChange
같은 사용자의 액션에 의해서 함수로 호출해야 한다. 바로onClick={setShowPopup(false)}
이렇게 넣을 경우 함수 호출 결과가 렌더링이 되고undefined
가 반환되므로 아무런 결과를 얻을 수 없다. (내가 어제 뒤로가기를 그렇게 해서 시간을 날렸다! 🥲) 따라서 꼭 꼭 꼭{}
안에 위처럼 화살표 함수로 정의하거나 리턴문 외부에서 함수 정의 후 전달해야 한다!const togglePopup = (event) => { setShowPopup(!showPopup) // showPopup?setShowPopup(!showPopup) : setShowPopup(event.target); //showPopup?setShowPopup(false) : setShowPopup(true); }; ~ ~ ~ return ( ~~~ <button className="close" onClick={togglePopup}> ~~~ );
혹은
togglePopup
를 다음과 같이 작성해 안과 밖의 팝업창이 같이 함수를 공유할 수 있다. 위에는event.target
으로false
가 아니게 만들었는데, 하고 보니 이게 더 간단하고 명확한 방법 같다.
function Parent() { return ( <div className="parent"> <h1>I'm the parent</h1> <Child text="really?">I'm the child</Child> </div> ); }; function Child(props) { console.log(props) // 객체형태 {text: "really?", children: "I'm the eldest child"} return ( <div className="child"> <p>{props.children}</p> </div> ); };
위 처럼
Parent()
에서<Child>
태그 안에text
형태로 전달할 수도 있고,textcontent
를 전달할 수도 있다.textcontent
는children
으로 받는다.
yes! 🙌 위의 App 함수를 살펴보자!
yes! 👏
예를 들어 웹으로 쇼핑을 한다고 할 때, 사용자가 액션을 취해서 바뀔 수 있는 검색이나, 정렬이나, 수량 등은 바뀔 수 있으므로 state이고, 바뀔 수 없는 각 아이템 리스트나 정보 같은 것들은 props라고 할 수 있다.
적합한 state와 props의 위치를 위해서는 컴포넌트 간의 여러 원칙을 생각해야 한다.
- 단일 책임 원칙! 하나의 컴포넌트는 하나의 일만해야 한다.
- 데이터는 위에서 아래로 흐르므로 props는 부모 컴포넌트에서 자식으로 전달된다.
- state는 최소화해야 한다. 많아지면 복잡해 진다.
- 컴포넌트 2개가 동일한 데이터를 props로 받는다면, 공통의 부모 컴포넌트에서 전달해야 한다.
yes! 🤓
React의 데이터는 위에서 아래로 흐른다. 그렇기 때문에 부모 컴포넌트에서 자식 컴포넌트로 props를 전달하고 자식 컴포넌트는 전달 받을 수 있다. 또 state에 따라 상태가 변화하면 위에서부터 리렌더링 되어 상태변화에 따른 결과값을 우리가 볼 수 있다.
function App() { const [msg, setMsg] = useState(""); return ( <div className="App"> <div>{msg}</div> <textarea placeholder="메세지를 작성해 주세요" className="input__message" onChange={(event) => setMsg(event.target.value)}> //화살표 함수로! </textarea> </div> ); }
onChange
로 상태변화를 전달하는데,setMsg
에event.target.value
로 작성된 내용을msg
에 넣어준다.
☺️내일두화이팅