<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, onClickname }) {
return (
<button
onClick={onClickname}
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}
>
{text}
</button>
);
}
// Btn 텍스트를 state에 연결시키기
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Change");
return (
<div>
<Btn text={value} onClickname={changeValue} />
<Btn text="Confirm" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
onClick={changeValue}
커스텀 컴포넌트 안에 넣는 이벤트리스너 처럼 생긴건 그냥 props이다.
html 요소 안에 넣는게 이벤트스너다.
따라서 커스텀 컴포넌트의 프로퍼티로 이벤트를 작성한 다음에, 반드시 html 요소가 있는 원래 버튼 함수로 프로퍼티이름을 보내서 html 요소에 이벤트리스너로 넣어줘야 한다.
❗️ 커스텀 컴포넌트 안에 쓴 props을 사용하려면 반!드!시! props에 오브젝트로 보내줘야 된다.
Btn(props) 이렇게 써서 props.프로퍼티이름 이렇게 안쓰는 이상 ㅇㅇ!!
Btn({text, changeValue}) 이러식으로 넣어줘야 쓸 수 있음!!
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, onClickname }) {
//언제 버튼이 다시 그려지는지
//밸류 체인지되면 re-render가 되는데
console.log(text, "was rendered ✅");
return (
<button
onClick={onClickname}
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}
>
{text}
</button>
);
}
// Btn 텍스트를 state에 연결시키기
// 부모의 상태를 바꾸는 함수(체인지벨류) // 밑에 온 클릭네임이 그 함수 실행시킴 ㅇㅇ..
//그리고 그건 자식이 실행시킴 위에 ㅇㅇ!
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Change");
return (
<div>
<Btn text={value} onClickname={changeValue} />
<Btn text="Confirm" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
첫번째 버튼은 상태가 바뀌었기 때문에 리렌더되는게 맞지만, 그런데 굳이 옆에 있는 Confirm 버튼은 리렌더링 될 필요가 없다.
하지만 React의 규칙에 의해 두 의 부모 컴포넌트인 App()이 상태(state)를 바꿨기 때문에 App()의 모든게 다시 re-render되었다.
걍 이런 feature가 리액트에 있구나~ 하고 알고 있으면 됨 ㅇㅇ!
이것을 막을 방법이 바로 React Memo! 마치 기억(memorize)하는 것 처럼!
이 컴포넌트가 다시 그려지는 것을 원하지 않는다고 memo할 수 있다. 단, props이 변경되지 않는 한에서.
첫 번째 버튼의 props는 state와 연결되어 있기 때문에 바뀌지만(value가 "Save Changes" 에서 "Revert Changes"로 바뀐다.) 두 번째 버튼은 아니다.
React.memo()
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({ text, onClickname }) {
//언제 버튼이 다시 그려지는지
//밸류 체인지되면 re-render가 되는데
console.log(text, "was rendered ✅");
return (
<button
onClick={onClickname}
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}
>
{text}
</button>
);
}
//🔥 메모라이즈드 버전의 버튼이 되도록 설정하고 아래에 버튼을 메모라이즈드버튼으로 수정해줌
const MemorizedBtn = React.memo(Btn);
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Change");
return (
<div>
<MemorizedBtn text={value} onClickname={changeValue} />
<MemorizedBtn text="Confirm" />
</div>
);
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
</html>
여기서 중요❗️한 점은 무엇이냐!
부모가 어떤 state(상태)라도 변경이 있다면, 모든 자식요소는 re-render(다시 그려지게)된다.
추후에 이런 이유로 내 어플리케이션이 느려질 수도 있다.
만약 부모 컴포넌트 안에 1,000개가 넘는 자식 컴포넌트가 들어 있는데 부모 컴포넌트 상태가 변경되면 자식 컴포넌트도 다시 랜더된다는 뜻이다. 그럼 당연히 엄청 느려지겠지.
여튼 React.memo() 는 우리의 컴포넌트들이 다시 그려질 때 효율적일 수 있도록 컨트롤 할 수 있다는 것을 보여주는 일종의 에시임 ㅇㅇ~