โ ๏ธ ์ ๋ฆฌํ ๋ด์ฉ์ ์คํ๋ ์๋ชป๋ ์ ๋ณด๊ฐ ์์ ์ ์์ต๋๋ค. ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์ ์ธ์ ์ผ๋ก ํด๊ฒฐ๋ ์ ์๋ ๋ฌธ์ ์์๋ ref์ฌ์ฉ์ ์ง์
Dialog
ย ์ปดํฌ๋ํธ์์ ์ฐฝ์ ์ด๊ณ ๋ซ์ ๋ย ref
๋ก DOM ๋
ธ๋์ ์ ๊ทผํ์ฌย open()
, close()
isOpen
๊ณผ ๊ฐ์ย state
ย ๋๋ย prop
์ ๋๊ฒจ์ฃผ์ด ํด๊ฒฐํ๋ ๊ฒ์ด ์ข๋ค.// render ๋ฉ์๋ ์์์ ref๊ฐ ์๋ฆฌ๋จผํธ์๊ฒ ์ ๋ฌ๋์์ ๋,
// ๊ทธ ๋
ธ๋๋ฅผ ํฅํ ์ฐธ์กฐ๋ ref์ current ์ดํธ๋ฆฌ๋ทฐํธ์ ๋ด๊ธฐ๊ฒ ๋๋ค.
const node = this.myRef.current;
์์ฑ์์์ย React.createRef()
๋ก ์์ฑ๋ย ref
๋ ์์ ์ ์ ๋ฌ๋ฐ์ DOM ์๋ฆฌ๋จผํธ๋ฅผย current
ย ํ๋กํผํฐ์ ๊ฐ์ผ๋ก์ ๋ฐ๋๋ค.
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
this.textInput.current.focus();
}
render() {
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
ref
ย ๊ฐ์ฒด๋ ๋ง์ดํธ๋ ์ปดํฌ๋ํธ์ ์ธ์คํด์ค๋ฅผย current
ย ํ๋กํผํฐ์ ๊ฐ์ผ๋ก์ ๋ฐ์ต๋๋ค.
class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
return (
// CustomTextInput์ด ํด๋์ค ์ปดํฌ๋ํธ์ผ ๋๋ง ์๋
// class CustomTextInput extends React.Component{ }
<CustomTextInput ref={this.textInput} />
);
}
}
function MyFunctionComponent() { // ํจ์ ์ปดํฌ๋ํธ
return <input />;
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
render() {
// ์ด ์ฝ๋๋ ๋์ํ์ง ์๋๋ค.
return (
<MyFunctionComponent ref={this.textInput} />
);
}
}
๋จ, DOM ์๋ฆฌ๋จผํธ๋ ํด๋์ค ์ปดํฌ๋ํธ์ ์ธ์คํด์ค์ ์ ๊ทผํ๊ธฐ ์ํดย ref
ย ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ํจ์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
function CustomTextInput(props) {
// textInput์ ref ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ํตํด ์ ๋ฌ๋๊ธฐ ์ํด์ ๊ผญ
const textInput = useRef(null);
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
ref ์ ๋ฌํ๊ธฐ
๋ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์ยref
๋ฅผ ์์ ์ยref
๋ก๋ถํฐ ์ธ๋ถ์ ๋ ธ์ถ์ํค๊ฒ ํ๋ค.
๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐย ref
๋ฅผ ๋ด๋ ค์ฃผ๋ฉด ์์ ์ปดํฌ๋ํธ๋ ์ ๋ฌ๋ฐ์ย ref
์ ์์ ์ย ref
๋ฅผ ๋ด์ ์ฌ๋ ค์ฃผ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
// ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ๋ง์ฐ์ค ์์น๋ฅผ ์ถ์ ํ๋ ๋ก์ง
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
// ์คํฌ๋ฆฐ ์ฃผ์๋ก ๋ง์ฐ์ค ์ปค์๋ฅผ ์์ง์ด๋ฉด, ์ปดํฌ๋ํธ๊ฐ ๋ง์ฐ์ค์ (x, y) ์ขํ๋ฅผ <p>์ ๋ํ๋จ
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
<h1>Move the mouse around!</h1>
<p>The current mouse position is ({this.state.x}, {this.state.y})</p>
</div>
);
}
}
๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ค๋ฉด?
class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class Mouse extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
<Mouse>๊ฐ ๋ฌด์์ ๋ ๋๋งํ๋์ง์ ๋ํด ๋ช
ํํ ์ฝ๋๋ก ํ๊ธฐํ๋ ๋์ ,
`render` prop์ ์ฌ์ฉํ์ฌ ๋ฌด์์ ๋ ๋๋งํ ์ง ๋์ ์ผ๋ก ๊ฒฐ์ ํ ์ ์๋ค.
*/}
{this.props.render(this.state)}
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
{// render ํจ์์ prop์ผ๋ก ์ ๋ฌํด์ค }
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
์ฆ, render prop์ ๋ฌด์์ ๋ ๋๋งํ ์ง ์ปดํฌ๋ํธ์ ์๋ ค์ฃผ๋ ํจ์์ด๋ค.
HOC(higher-order-components)ํจํด์ render props pattern์ ์ ์ฉํ ์ ์๋ค.
function withMouse(Component) {
return class extends React.Component {
render() {
return (
<Mouse render={mouse => (
<Component {...this.props} mouse={mouse} />
)}/>
);
}
}
}
์ด๋ค ํจ์ํ prop์ด๋ render prop์ด ๋ ์ ์๋ค.
// render๋ณด๋ค children์ ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
<Mouse children={mouse => (
<p>The mouse position is {mouse.x}, {mouse.y}</p>
)}/>
React.PureComponent์์ render props pattern์ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํ๋ค.
class Mouse extends React.PureComponent {
// ์์ ๊ฐ์ ๊ตฌํ์ฒด...
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
{/*
<MouseTracker>๊ฐ ๋ ๋๋ง ๋ ๋๋ง๋ค <Mouse render>์ prop์ผ๋ก ๋์ด๊ฐ๋
ํจ์๊ฐ ๊ณ์ ์๋ก ์์ฑ๋๋ค.
*/}
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
๋ฐ๋ผ์ ์๋์ฒ๋ผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ prop์ ์ ์ํด์ผ ํ๋ค.
class MouseTracker extends React.Component {
// `this.renderTheCat`๋ฅผ ํญ์ ์์ฑํ๋ ๋งค์๋๋ฅผ ์ ์
// ์ด๊ฒ์ render๋ฅผ ์ฌ์ฉํ ๋ ๋ง๋ค *๊ฐ์* ํจ์๋ฅผ ์ฐธ์กฐ
renderTheCat(mouse) {
return <Cat mouse={mouse} />;
}
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={this.renderTheCat} />
</div>
);
}
}