[React] ์คํฌ๋กค๋ฐ์ค ์ฝ๋์ ์์๋ ์ด๋ ๊ธฐ๋ฅ ๊ตฌํ
๐๋ฆฌ์กํธ๋ฅผ ๋ค๋ฃจ๋ ๊ธฐ์ ๐ ์ฑ ์ ์๋ ref์์ ์ธ ์คํฌ๋กค ๋ฐ์ค ์กฐ์ ์ฝ๋๋ '๋งจ๋ฐ์ผ๋ก'๋ผ๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ์๋์ผ๋ก ์คํฌ๋กค์ ๋งจ ๋ฐ์ผ๋ก ๋ด๋ ค๊ฐ๊ฒ ํด์ฃผ๋ ๋ด์ฉ์ด๋ค.
ํ์ง๋ง, ๋๋ ์ฌ๊ธฐ์ ์์ฉํ๊ธฐ ์ํด์ ๋ฒํผ์ ๋๋ฅผ ๋๋ง๋ค ์คํฌ๋กค ๋ฐ์ค๊ฐ ์, ์๋๋ก ์ด๋ํ ์ ์๋๋ก ๊ตฌํํ๊ณ ์ถ์๋ค.
๋ฆฌ์กํธ๋ฅผ ๋ค๋ฃฌ์ง ์ผ๋ง ๋์ง ์์ ์ฒ์์๋ ์ด๋ฏธ ์์ฑ๋์ด์ ธ ์๋ ์ฝ๋๋ฅผ ์ด๋์๋ถํฐ ์ ๋์ผ ๋ ์ง ๋ง๋งํ์ง๋ง, ์์์ ํ๋ ์์ ๋ค์ ์ด์ฉํด์ ๊ณง์ฅ ๋ฐฉ๋ฒ์ ์ฐพ์๋ผ ์ ์์๋ค.
์ผ๋จ ์คํฌ๋กค์ด ๋ด๋ ค๊ฐ์์๋๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ฌ๋ผ์์ผํ๊ณ ,
์ฌ๋ผ๊ฐ์์ ๋๋ ๋ด๋ ค์์ผํ๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ๊ฐ์ด ๋ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํ ์ด๊ธฐ๊ฐ๋ค์ ์ค์ ํด์ค์ผํ๋ค.
์ด์ ๋ฐ๋ผ ์ ์ฅ์์์ ์์ ๋ค์ ๋ ์ฌ๋ ค์ state์ ๋ํ ์ด๊ธฐ๊ฐ์ App.js์ ์ค์ ํด์ฃผ์๋ค.
state = {
upDown: 'u', //์ฒ์์ u๋ผ๊ณ ์ค์ , ์ง๊ธ ์์น๊ฐ up์ ์๋ค๋ ๋ป
value: 'To Bottom' //์ด์ ๋ด๋ ค๊ฐ์ผํ๋ค๋ ๋ป์ ์ค์
}
์์ ์ฝ๋์ฒ๋ผ ๋ง์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฒํผ์ ๋๋ฆ์ ๋ฐ๋ผ state ๊ฐ์ด u -> d ๋ก, To Bottom -> To Top์ผ๋ก ๋ฐ๊ฟ์ค ์ ์์ด์ผํ๋ค.
์ด๋ฐ ์ค์ ์ ํด์ฃผ๊ธฐ ์ํด์ ํจ์ upOrDown์ ๋ง๋ค์ด์ ์ด์ฉํ๋ค.
upOrDown = () => {
if (this.state.upDown === 'u') { //์๋ ํด๋น state๊ฐ u์์ผ๋ฉด
this.setState({
upDown: 'd', // u->d
value: 'To Top' //To Bottom -> To Top์ผ๋ก ๋ฐ๊ฟ์ค
});
}
else {
this.setState({
upDown: 'u',
value: 'To Buttom'
})
}
}
์ด upOrDownํจ์๋ '์ด๋'์ด๋ผ๋ ๋ฒํผ์ ๋๋ฌ์ค๋๋ง๋ค state๊ฐ ๋ฐ๊ปด์ผ๋๊ธฐ ๋๋ฌธ์ ๋ ํฐํจ์ ์์ ์๋์ ์ฝ๋์ฒ๋ผ ์์ฑํด์ค๋ค.
render() {
return (
<>
<ScrollBox ref={(ref) => this.scrollBox = ref} />
<button onClick={() => {
this.scrollBox.scrollChange(this.state.upDown);
this.upOrDown(); //ํด๋ฆญ ๋ ๋๋ง๋ค state๊ฐ ๋ฐ๊ฟ์ฃผ๊ธฐ
}}>
์ด๋
</button>
</>
);
}
๊ทธ๋ ๋ค๋ฉด, ์คํฌ๋กค๋ฐ์ค๊ฐ ๊ตฌํ๋์ด์๋ ScrollBox.js ํ์ผ์ ๋ฌด์์ ๋ฐ๊ฟ์ฃผ๊ณ ์ถ๊ฐํด์ค์ผํ ๊น?
๋ฐ๋ก ์ฒ์์ ๋ฐ์์ง๋ state๊ฐ์ ๋ฐ๋ผ ์๋ก ์ฌ๋ฆฌ๊ณ , ์๋๋ก ์คํฌ๋กค์ ๋ด๋ฆฌ๋ ํจ์๋ฅผ ๋ง๋ค์ด์ผํ๋ค.
๋งค๊ฐ๋ณ์ param์ ๋ฐ๋๋ค. ๋ง์ฝ param์ ๊ฐ์ด u๋ผ๋ฉด, ๋ด๋ฆฌ๋๋ก ๋ง๋ค๊ณ ์๋๋ผ๋ฉด ์คํฌ๋กค์ ์ฌ๋ ค์ผํ๋ค.
์ด๋ ์ด๋ป๊ฒ ๊ตฌํํ๋ฉด ์ข์๊น?
//ScrollBox.js
scrollChange = (param) => {
const { scrollHeight, clientHeight } = this.box;
/*์ ์ฝ๋๋ ๋น๊ตฌ์กฐํ ํ ๋น ๋ฌธ๋ฒ ์ฌ์ฉ
๋ค์ ์ฝ๋์ ๋์ผ
const scrollHeight = this.box.scrollHeight;
const clientHeight = this.box.clientHeight;
*/
if (param === 'u') { //up์ผ๋ ๋ด๋ฆด ์ค๋น
this.box.scrollTop = scrollHeight - clientHeight;
}
else {
this.box.scrollTop = 0;
}
}
์์ ๊ฐ์ ํจ์๋ฅผ ๋ง๋ค์ด์ฃผ์๋ค.
์ฌ๊ธฐ์ ScrollTop์ ์ธ๋ก ์คํฌ๋กค๋ฐ ์์น, ScrollHeight๋ ์คํฌ๋กค๋ฐ์ค์ ๋์ด๋ก 650px์ด๊ณ , clientHeight๋ ์คํฌ๋กค์ด ์๋ ๋ฐ์ค์ ๋์ด๋ก 300์ ์๋ฏธํ๋ค.
์คํฌ๋กค๋ฐ๋ฅผ ๋ฐ์ผ๋ก ๋ด๋ฆฌ๊ธฐ ์ํด์๋ scrollHeight์์ clientHeight๋ฅผ ๋ด๋ ค์ฃผ๋ฉด ๋๊ฒ ์ฃ ??
์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค!
App.js
import React, { Component } from 'react';
import './App.css';
import ValidationSample from './ValidationSample';
import ScrollBox from './ScrollBox';
class App extends Component {
state = {
upDown: 'u',
value: 'To Bottom'
}
upOrDown = () => {
if (this.state.upDown === 'u') {
this.setState({
upDown: 'd',
value: 'To Top'
});
}
else {
this.setState({
upDown: 'u',
value: 'To Buttom'
})
}
}
render() {
return (
<>
<ScrollBox ref={(ref) => this.scrollBox = ref} />
<button onClick={() => {
this.scrollBox.scrollChange(this.state.upDown);
this.upOrDown();
}}>
์ด๋
</button>
</>
);
}
}
export default App;
ScrollBox.js
import React, { Component } from 'react';
class ScrollBox extends Component {
scrollChange = (param) => {
const { scrollHeight, clientHeight } = this.box;
/*์ ์ฝ๋๋ ๋น๊ตฌ์กฐํ ํ ๋น ๋ฌธ๋ฒ ์ฌ์ฉ
๋ค์ ์ฝ๋์ ๋์ผ
const scrollHeight = this.box.scrollHeight;
const clientHeight = this.box.clientHeight;
*/
if (param === 'u') { //up์ผ๋ ๋ด๋ฆด ์ค๋น
this.box.scrollTop = scrollHeight - clientHeight;
}
else {
this.box.scrollTop = 0;
}
}
render() {
const style = {
border: '1px solid black',
height: '300px',
width: '300px',
overflow: 'auto',
position: 'relative'
};
const innerStyle = {
width: '100%',
height: '650px',
background: 'linear-gradient(white,black)'
}
return (
<div
style={style}
ref={(ref) => { this.box = ref }}>
<div style={innerStyle} />
</div>
);
}
}
export default ScrollBox;