λ΄κ° μ¬μ©νκ³ react-custom-scrollbar
νκ³ μ ν΅ν©νλ €λ FixedSizeList
.
μ΄ λ¬Έμ μ λν ν΄κ²°μ±
μ react-virtualized
: https://github.com/bvaughn/react-virtualized/issues/692#issuecomment -339393521
κ·Έλ¬λ μ½λλ λ€μ ν¨μμμ μ€ν¬λ‘€μ Uncaught TypeError: Cannot read property 'handleScrollEvent' of undefined
μ€λ₯λ₯Ό λ°μμν΅λλ€.
handleScroll = ({ target }) => {
const { scrollTop, scrollLeft } = target;
const { Grid: grid } = this.List;
grid.handleScrollEvent({ scrollTop, scrollLeft });
}
fixedSixe <List
κ΅¬μ± μμμ ref={ instance => { this.List = instance; } }
μ μΆκ°νμ΅λλ€.
μ΄ λΌμ΄λΈλ¬λ¦¬μ react-virtualized
μ μμ ν λ€λ₯Έ ꡬνμ
λλ€. react-virtualized
λ¬Έμ μμ λ³Ό μμλ μΌλ°μ μΈ κΈ°μ μ μ’
μ’
μ κ·Ό λ°©λ²μ λν μ μ©ν ννΈλ₯Ό μ 곡 ν μ μμ§λ§ μ΄μ κ°μ ꡬ체μ μΈ κ΅¬ν μΈλΆ μ¬νμ μ μ© ν μ μμ΅λλ€. ( react-virtualized
μμ List
λ Grid
κ΅¬μ± μμλ₯Ό μ₯μν©λλ€. react-window
μμλ μ±λ₯κ³Ό ν¬κΈ°λ₯Ό κ°μ νκΈ° μν΄ λ³λμ κ΅¬μ± μμμ
λλ€.)
react-custom-scrollbar
μ κ°μ κ²μ΄ react-window
μ (μ) ν¨κ» μλν μ§ λͺ¨λ₯΄κ² μ΅λλ€. μμ§ν λ§ν΄μ μ§μνκ³ μΆμ κ²μ μλλλ€. 컀μ€ν
μ€ν¬λ‘€λ°λ μ±λ₯μ λ―ΈμΉλ μν₯ λλ¬Έμ μΌλ°μ μΌλ‘ λμ μκ°μ΄κΈ° λλ¬Έμ
λλ€. κ·Έλμμ΄ λ¬Έμ λ₯Ό λ§λ¬΄λ¦¬νκ² μ΅λλ€.
κ·Έλ¬λ νμ μ§λ¬Έμ΄ μμΌλ©΄ κ³μ μ±ν ν μ μμ΅λλ€ π
μ΄κ²μ λν΄ λκ° μμλΌ κ²μ
λλ€. react-window
μ¬μ©μ κ΄μ¬μ΄ μμ΅λλ€. κ°λ³κ³ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° λλ¬Έμ
λλ€. λλ μ¬μ©μ μ§μ μ€ν¬λ‘€λ°λ₯Ό μ¬μ©νλ κ²μ μ’μνμ§ μμ§λ§ λ΄ μ μμ μμ§ μμΌλ―λ‘ μ€ν¬λ‘€λ°μ λν μ¬μ©μ μ§μ λμμΈμ΄ νμν©λλ€.
μ΅μ
μ κ²½μ° react-virtualized
ν©λλ€.
κ°μ¬ :)
@ Rahul-Sagore λΉμ μ react-window
μ ν¨κ» μλνλ μ¬μ©μ μ μ μ€ν¬λ‘€λ°λ₯Ό μ»μμ΅λκΉ?
μλ, κ·Έλ΄ μκ°μ΄ μμμ΄. νμΈνκ³ μμλΌ νμκ° μμ΅λλ€.
@bvaughn μ΄ https://codesandbox.io/s/00nw2w1jv
λ λμ λ°©λ²μ Scrollbars
λ₯Ό outerElementType
const CustomScrollbars = ({ onScroll, forwardedRef, style, children }) => {
const refSetter = useCallback(scrollbarsRef => {
if (scrollbarsRef) {
forwardedRef(scrollbarsRef.view);
} else {
forwardedRef(null);
}
}, []);
return (
<Scrollbars
ref={refSetter}
style={{ ...style, overflow: "hidden" }}
onScroll={onScroll}
>
{children}
</Scrollbars>
);
};
const CustomScrollbarsVirtualList = React.forwardRef((props, ref) => (
<CustomScrollbars {...props} forwardedRef={ref} />
));
// ...
<FixedSizeList
outerElementType={CustomScrollbarsVirtualList}
{...rest}
/>
outerElementType
λλ innerElementType
μ¬μ©νμ¬ μΌλ§λ λ§μ κ³ κΈ κΈ°λ₯μ μ¬μ©ν μ μλμ§ μ λ§ μ’μν©λλ€.
λ°μ μ°½ νλ¨μ μ€ν¬λ‘€ μμΉλ₯Ό κ°μ§νλ €κ³ ν©λλ€.
κ°λ₯ν κΉμ? κ·Έκ²μ λν μμ΄λμ΄κ° μμ΅λκΉ? codesandbox μμ λ₯Ό κ°κ³ μΆμ΅λλ€.
μ¬μ© κ°λ₯ν ref propsλ₯Ό μ¬μ©νμ¬ scrollHeight
@rufoot λͺ©λ‘μ μμ²ν μ μμ΅λλ€.
λλ μνμμ scrollHeight
μ μ¬μ©νλ €κ³ νμ΅λλ€. κ·Έλ¬λ λλ κ·Έκ²μ scrollHeight
μμ±μ΄ μλ€κ³ μκ°ν©λλ€.
@bvaughn κ·Έκ²μ λν΄ μ΄λ€ μκ°μ΄ μμ΅λκΉ?
scrollToRow200Auto = () => {
this.listRef.current.scrollToItem(200);
console.log("current position = ", this.listRef.current.props.scrollHeight)
};
νμ¬ μμΉ = μ μλμ§ μμ
@rufoot λκ° https://codesandbox.io/s/4zjwwq98j4 ?
https://codesandbox.io/embed/jzo2lool2y
λ°μ μ°½ νλ¨μμ μλλ‘ μ€ν¬λ‘€νλ©΄ νλμ κ²½κ³ λ₯Ό λ³Ό μ μμ΅λλ€.
@piecyk outerElementType
μ루μ
μ μλνμ§λ§ λ§€μ° λ립λλ€.
react-scrollbars-custom
μλνμ΅λλ€. λ λλ¦¬μ§ λ§ μ¬μ ν λ립λλ€. λκ΅°κ° μ¬μ©μ μ§μ μ€ν¬λ‘€ λ§λλ₯Ό μ¬μ©νμ¬ μ§μ°μ λ¬Έμ κ° μμ΅λκΉ?
@ jancama2 λ κ·Έκ²μ λ°°ν
@rufoot λκ° https://codesandbox.io/s/4zjwwq98j4 ?
ꡬνμ μ¬μ©νκ³ μμ§λ§ forwardedRefκ° ν¨μκ° μλλΌλ μ€λ₯κ° λ°μν©λλ€.
λ΄κ° ν΄κ²°νλ €λ μ±μ λ¬Έμ λ νλͺ© λͺ©λ‘μ΄ λ§κ³ νλͺ©μ ν΄λ¦νλ©΄ μ±μ΄ λ€λ₯Έ κ²½λ‘λ‘ λ¦¬λλ μ λλ―λ‘ μ€ν¬λ‘€ μμΉ (μλ§λ reduxμμ)λ₯Ό μΆμ ν΄μΌν©λλ€. κ·Έλ° λ€μ κ²½λ‘ λ³κ²½ ν μ€ν¬λ‘€ μμΉλ₯Ό μ€μ νμμμ€.
@piecyk λ₯Ό react-window-infinite-loader
μ InfiniteLoaderμ κ²°ν© ν΄ λ³΄μ
¨λμ ?
react-scrollbars-custom
νκ³ μμΌλ©° 무ν λ‘λκ° κΉ¨μ§λ κ² κ°μ΅λλ€.
λ΄ μ½λ :
<InfiniteLoader isItemLoaded={isItemLoaded} itemCount={items.total} loadMoreItems={loadMoreItems}>
{({
onItemsRendered,
ref,
}: {
onItemsRendered: (props: ListOnItemsRenderedProps) => any;
ref: React.Ref<any>;
}) => (
<List
height={TABLE_HEIGHT}
width={width}
itemCount={items.total}
itemSize={ROW_HEIGHT}
onItemsRendered={onItemsRendered}
itemData={{ items }}
ref={ref}
outerElementType={Scrollbar}
>
{Row}
</List>
)}
</InfiniteLoader>
μ λ°μ΄νΈ : 무ν μ€ν¬λ‘€ κ΅¬μ± μμμ κ΄λ ¨μ΄ μλ€κ³ μκ°νμ§ μμ΅λλ€. μ¬μ©μ μ μ μ€ν¬λ‘€λ°μμ μλνλλ‘ ν μ μμ΅λλ€.
λκ΅°κ°κ° react-scrollbars-custom ꡬνμ λμ 곡μ ν μ μλ€λ©΄ κ°μ¬νκ² μ΅λλ€.
@ranihorev κ·Έ ν¨ν€μ§λ₯Ό μ¬μ©ν΄μΌν©λκΉ? μμμ 곡μ ν μ½λ ν @piecyk λ react-custom-scrollbarsλ₯Ό μ¬μ©νλ©° μ μλν©λλ€ (refλ₯Ό μμ± ν λ μμΈ, μ΄λ€ μ΄μ λ‘ λ΄ μ½λμμ null μΈ κ²½μ°)
μκ² μ΅λλ€. λ€μ λ¬»κ² μ΅λλ€. @piecyk μμ μ½λ μνμ μ¬μ©νκ³ μμ΅λλ€ ( @simjesμ λ΅μ₯ ν
<TreeRoot
onDragOver={e => this.onDragOver(e)}
>
<AutoSizer>
{({ height, width }) => (
<List
treeRef={this.props.treeRef}
width={width}
height={height}
itemSize={index => rowHeights[index]}
itemCount={nodeTree.length}
itemData={{
nodeTree,
expandedNodes,
nodesFetching,
nodesFetchingFailed,
selectedNode,
selectedNodeId,
resetRowHeight: this.resetRowHeight,
}}
outerElementType={TreeScrollbar}
outerRef={this.props.outerRef}
onScroll={({ scrollOffset, scrollUpdateWasRequested }) => {
if (scrollUpdateWasRequested) {
console.log('scrollOffset: ', scrollOffset);
}
}}
>
{Node}
</List>
)}
</AutoSizer>
</TreeRoot>
CustomScrollbars λ° CustomScrollbarsVirtualListλ₯Ό μ¬μ©μμ λμΌνκ² κ΅¬ννμ§λ§ refλ νμ nullμ λλ€. AutoSizerμ λΆλͺ¨λ₯Ό μ¬μ©νλ κ΅¬μ± μμμμ refλ₯Ό λ§λ€λ €κ³ μλνμ§λ§ νμ nullμ λλ€. μ΄μ λ₯Ό μ΄ν΄νλ λ° λμμ μ£Όμλ©΄ κ°μ¬νκ² μ΅λλ€. μμμ μΈκΈνλ―μ΄ μ€ν¬λ‘€ μμΉλ₯Ό μΆμ νκ³ λͺ©λ‘μ΄ λ§¨ μλ‘ μ΄λνμ§ μλλ‘ λ΄ μ±μ κ²½λ‘ λ³κ²½μ μ€μ ν μ μμ΄μΌν©λλ€.
@ChristopherHButler μ΄λ―Έ λ΄ μ½λμμ ν΄λΉ ν¨ν€μ§λ₯Ό μ¬λ¬ λ² μ¬μ©νκ³ μμΌλ―λ‘ λμΌν ν¨ν€μ§λ₯Ό κ³μ μ¬μ©νκ³ μΆμ΅λλ€. I μ루μ μ λ§€μ° μ μ¬νμ§λ§ μ λ°μ΄ν°λ₯Ό ptoperly κ°μ Έ μ€μ§ μμ΅λλ€.
@ChristopherHButler λ λ¬Έμ μ μ½λ μλ λ°μ€ μμ μμ΄λ λ§νκΈ°κ° μ λ§ μ΄λ ΅μ΅λλ€. 무μΈκ°λ₯Ό 곡μ ν μ μμ΅λκΉ?
μ¬κΈ°μ κΈ°λ³Έ μμ΄λμ΄λ react-custom-scrollbarsμμ refλ₯Ό μ€μ νμ¬ react-windowκ°
AutoSizer λλ VariableSizeListλμ΄ μμ μμμ κ°μ΄μ΄ μ κ·Ό λ°©μμΌλ‘ μλν©λλ€.
https://codesandbox.io/s/react-window-custom-scrollbars-t4352
@ranihorev μ½λ μλ λ°μ€ μμ λ 곡μ ν μ μμ΅λκΉ?
@piecyk κ°λ¨ν (κ·Έλ¦¬κ³ κΉ¨μ§) μμ λ₯Ό λ§λλλ€.
https://codesandbox.io/s/bvaughnreact-window-fixed-size-list-vertical-64kzh?fontsize=14
λλ λν λ€λ₯Έ λ³νμ μλνμ§λ§ (μ : μ°Έμ‘°λ₯Ό μ€ν¬λ‘€λ¬ λνΌλ‘ μ€μ ) μ±κ³΅νμ§ λͺ»νμ΅λλ€ ...
κ°μ¬!
@ranihorev μ΄ μ κ·Ό λ°©μμ μ¬μ©μ μ§μ μ€ν¬λ‘€ ꡬνμ κ΄κ³μμ΄ λμΌν©λλ€. μ€ν¬λ‘€μ λ΄λΉνλ λμΌν μμμ λν μ°Έμ‘°λ₯Ό μ€μ νκ³ ν΄λΉ μ€ν¬λ‘€ μ΄λ²€νΈλ₯Ό μ²λ¦¬ν΄μΌν©λλ€.
react-scrollbars-custom
λ λ λλ§ μν ν¨ν΄μ μ¬μ©νμ¬ λ μ’μ APIλ₯Ό μ 곡νλ―λ‘ https://codesandbox.io/s/bvaughnreact-window-react-scrollbars-custom-pjyxs μ κ°μ μμ
μ μν ν μ μμ΅λλ€.
νλ‘νμΌ λ§μνμ§ μμμ΅λλ€. λμμ΄ λμκΈ°λ₯Ό λ°λλλ€.
@piecyk μ¬κΈ°μμ λ°λͺ¨ μμ μνκ³ μμ΅λλ€ : https://codesandbox.io/s/4zjwwq98j4 . μ€ν¬λ‘€ μμΉλ₯Ό μ€μ ν μ μλλ‘ onScrollStopμ μ¬μ©νμ¬ reduxμμ μμ μ μ λ¬νκ³ μΆμ΅λλ€ (μ΄ μ€λ λμ μμ΄λμ΄ : https://github.com/malte-wessel/react-custom-scrollbars/issues/146 μ΄μ§λ§ onScrollStart λ° onScrollStopμ΄ λ΄ μ½λ λ λ°λͺ¨μμ μλνμ§ μλ κ² κ°μ΅λλ€. κ·Έ μ΄μ λ₯Ό μκ³ μμ΅λκΉ? λͺ©λ‘μμ μ€ν¬λ‘€λ°λ‘ μνμ μ λ¬ν μμλ λ°©λ²μ΄ μμ΅λκΉ?
@ChristopherHButler μ΅μ μ μ νμ 컨ν μ€νΈλ₯Ό μ¬μ©νμ¬ μνμ μ λ¬νλ κ²μ λλ€.
https://codesandbox.io/s/bvaughnreact-window-fixed-size-list-vertical-v2-usi1m
--- νΈμ§ λ¨
κ²½λ‘κ° λ³κ²½ λ λ μ 체 λͺ©λ‘μ λ§μ΄νΈ ν΄μ νλ©΄ μμ
μ μ λ¬ν μ μμ΅λλ€. Last scrollOffsetμ refμ μ μ₯λκ³ VariableSizeListμ onScroll: function
λ₯Ό μ¬μ©νμ¬ λͺ¨λ μ€ν¬λ‘€ λ³κ²½μ μ
λ°μ΄νΈ λ μ μμ΅λλ€. κ·Έλ¬λ©΄ μνμ Scrollbarsμ μ λ¬ν νμκ° μμ΅λλ€.
@piecyk κ΅μ₯ν©λλ€, κ°μ¬ν©λλ€!
btw, νμν κ²μ onScroll
ν¨μ (λ΄κ° λμΉ) λΏμ΄κ³ refλ₯Ό μ λ¬ν νμκ° μ νμλ κ² κ°μ΅λλ€.
https://codesandbox.io/s/bvaughnreact-window-react-scrollbars-custom-99dn1
@piecyk μ£μ‘ν©λλ€. VariableSizeListμ ꡬνμ΄ AutoSizerμ λνλμ΄ μκ³ μ΄λ₯Ό λ λλ§νλ κ΅¬μ± μμλ ν΄λμ€ κΈ°λ° κ΅¬μ± μμμ΄λ―λ‘ μ»¨ν μ€νΈλ₯Ό μ¬μ©ν μ μλμ§ νμ€νμ§ μμ΅λλ€. μ΄κ²μ΄ λ΄κ° onScrollStopμ μλμν¬ μμλ μ΄μ μΌκΉμ?
λΉ λ₯Έ μ
λ°μ΄νΈ:
κ΅¬μ± μμ μνλ₯Ό μΆκ°νκ³ onScrollλ‘ μ€μ νμ΅λλ€.
`
class BaseTree extends Component {
...
μν = {scrollPosition : 0,};
...
listRef = React.createRef ();
outerRef = React.createRef ();
...
render {
const {λ
Έλ, nodesFetching, nodesFetchingFailed, extendedNodes, selectedNode} = this.props;
λ°ν (
{({λμ΄, λλΉ}) => ( ref = {this.listRef}
className = "λͺ©λ‘"
outerRef = {this.outerRef}
outerElementType = {TreeScrollbar}
λλΉ = {λλΉ}
λμ΄ = {λμ΄}
onScroll = {({scrollOffset}) => this.setState ({scrollPosition : scrollOffset})}
itemSize = {index => rowHeights [index]}
itemCount = {nodeTree.length}
itemData = {{
nodeTree,
extendedNodes,
nodesFetching,
nodesFetchingFailed,
selectedNode,
selectedNodeId,
resetRowHeight : this.resetRowHeight,
}}
>
{λ§λ}
)}
);
}}
const mapStateToProps = μν => ({
scrollPosition : selectors.getTreeScrollPosition (state),
});
const mapDispatchToProps = dispatch => ({
setTreeScrollPosition : position => dispatch (actions.setTreeScrollPosition ({position})),
});
κΈ°λ³Έ μ°κ²° λ΄λ³΄λ΄κΈ° (mapStateToProps, mapDispatchToProps) (BaseTree);
`
κ·Έλ° λ€μ componentWillUnmoutμμ λ€μκ³Ό κ°μ΄ reduxμμ μμΉλ₯Ό μ€μ νλ μμ μ μ λ¬ν©λλ€.
componentWillUnmount() {
this.props.setTreeScrollPosition(this.state.scrollPosition);
}
λ΄ μ μΌν λ¬Έμ λ κ΅¬μ± μμκ° λ€μ μ₯μ°© λ λ μ€ν¬λ‘€ μμΉλ₯Ό μ€μ ν μ μλ€λ κ²μ λλ€. λ€μκ³Ό κ°μ΄ this.listRefμμ scrollTop λ©μλμ μ‘μΈμ€ ν΄ λ³΄μμ΅λλ€.
this.listRef.current.scrollTop()
νμ§λ§ ν¨μκ° μλλΌλ μ€λ₯κ° λ°μν©λλ€. μ€ν¬λ‘€ μμΉλ₯Ό μ€μ νλ λ° μ¬μ©ν μμλ μμ± (this.listRef λλ this.outerRef)μ μ λͺ¨λ₯΄κ² μ΅λλ€. λ€μκ³Ό κ°μ΄ BaseTreeμ componentDidMountμμ μ€μ ν μ μλ€κ³ μκ°νμ΅λλ€.
componentDidMount() {
const { scrollPosition } = this.props;
if (this.listRef.current) {
// console.log('initializing scroll position to : ', scrollPosition);
this.listRef.current.scrollTop(scrollPosition);
}
}
μ΄ μμ
μ λμμ μ£Όμλ©΄ λλ¨ν κ°μ¬νκ² μ΅λλ€!
νΈμ§ : λ―Έμνμ§λ§ λ΄ μ½λκ°μ΄ νΈμ§κΈ°μμ μ¬λ°λ₯΄κ² μμμ μ§μ νμ§ μλ κ² κ°μμ μ¬κ³Όλ립λλ€.
@ranihorev forward ref
λ°μ μ°½μ scrollTo, scrollToItem
κ°μ κΈ°λ₯μ΄ μλν΄μΌν©λλ€.
@ChristopherHButler 컨ν μ€νΈλ λ¬Έμμμ λΉλ λλλ‘ μ ννκ² μλν΄μΌν©λλ€.
컨ν μ€νΈλ λͺ¨λ λ 벨μμ μλμΌλ‘ μνμ μ λ¬ν νμμμ΄ κ΅¬μ± μμ νΈλ¦¬λ₯Ό ν΅ν΄ λ°μ΄ν°λ₯Ό μ λ¬ν μμλ λ°©λ²μ μ 곡ν©λλ€.
κ·Έλ¬λ μμ μ μΈκΈνλ―μ΄ κ²½λ‘ λ³κ²½μ μ 체 κ΅¬μ± μμλ₯Ό λ§μ΄νΈ ν΄μ νλ©΄ μνμ μ λ¬ν νμκ° μμ΅λλ€. μ€ν¬λ‘€μ΄ λ°μνλ λμ νμνμ§ μκΈ° λλ¬Έμ μνμ scrollPosition
λ₯Ό μ μ₯νμ§ μκ³ , λ€μ λ λλ§νμ§ μκ³ refμ μ μ₯ν©λλ€.
onScroll={({ scrollOffset }) => this.setState({ scrollPosition: scrollOffset })}
// to
lastScrollOffsetRef = React.createRef(0);
<List
onScroll={({ scrollOffset }) => {
this.lastScrollOffsetRef.current = scrollOffset
}}
// ...rest
/>
// then in
componentWillUnmount() {
this.props.setTreeScrollPosition(this.lastScrollOffsetRef.current);
}
outerRef
μ κ΄ν΄μλ κ·νμ κ²½μ°μλ νμνμ§ μμ΅λλ€. listRef.current.scrollTo
λ μ¬μ©νλ €λ μ¬λ°λ₯Έ λ°©λ²μ
λλ€. componentDidMount
μμ λ©μλλ₯Ό νΈμΆνλ μμ΄λμ΄κ° μ ννκ³ μλν΄μΌν©λλ€.
https://codesandbox.io/s/bvaughnreact-window-fixed-size-list-vertical-80zo7
refsλ₯Ό μ€μ νλ λμ νμ΄λ° λ¬Έμ μ²λΌ 보μ λλ€. AutoSizerκ° this.listRef.currentλ₯Ό μ μλμ§ μκ² λ§λλ List λ λλ§μ μ§μ°μν¬ μ μμ΅λλ€.
hacky μ΅μ μ setTimeoutμΌλ‘ λ°μ λΌμ΄ν μ¬μ΄ν΄μ μ€λ¨νκ³ λ€μ ν±μμ refλ₯Ό νΈμΆνλ κ²μ λλ€.
componentDidMount() {
window.setTimeout(() => {
if (this.listRef.current) {
this.listRef.current.scrollTo(this.props.scrollPosition);
}
}, 0);
}
@piecyk λμμ μ£Όμ μ κ°μ¬ν©λλ€, μ λ§ κ°μ¬ν©λλ€ :)
κ°μ¬ν©λλ€ @piecyk μλνλ κ² κ°μ΅λλ€. κ²½λ‘ λ³κ²½ ν λ§μ΄νΈμ μ½κ°μ κΉλ°μμ΄ μμ§λ§ ν¨κ» μ΄ μ μμ΅λλ€ :) λν classNameμ μ¬μ©νμ¬ scrollPositionμ μ λ¬νκ³ CustomScrollbarsμ refSetterμ scrollTopμ μ€μ νλ λ λ€λ₯Έ ν΄νΉμ μλνμ΅λλ€.
if (scrollbarsRef) {
forwardedRef(scrollbarsRef.view);
// HACK
scrollbarsRef.scrollTop(className);
}
μ μλνλ κ² κ°μ΅λλ€.
λͺ¨λ λμμ λ€μ νλ² κ°μ¬λ립λλ€. λλ¨ν κ°μ¬ν©λλ€ !! ππ»
μνκΉκ²λμ΄ λ¬Έμ μ λͺ¨λ μμ κ° μ λλ‘ μλνμ§ μμ΅λλ€ (λλ‘λ λ§μ°μ€κ° μ€ν¬λ‘€μ μλ΅νμ§ μμ).
κ·Έλ¬λμ΄ μμ λ μλ²½νκ² μλν©λλ€!
@ranihorev μ΄ μ κ·Ό λ°©μμ μ¬μ©μ μ§μ μ€ν¬λ‘€ ꡬνμ κ΄κ³μμ΄ λμΌν©λλ€. μ€ν¬λ‘€μ λ΄λΉνλ λμΌν μμμ λν μ°Έμ‘°λ₯Ό μ€μ νκ³ ν΄λΉ μ€ν¬λ‘€ μ΄λ²€νΈλ₯Ό μ²λ¦¬ν΄μΌν©λλ€.
react-scrollbars-custom
λ λ λλ§ μν ν¨ν΄μ μ¬μ©νμ¬ λ μ’μ APIλ₯Ό μ 곡νλ―λ‘ https://codesandbox.io/s/bvaughnreact-window-react-scrollbars-custom-pjyxs μ κ°μ μμ μ μν ν μ μμ΅λλ€.
react-scrollbars-custom
μλνμ΅λλ€. λ λλ¦¬μ§ λ§ μ¬μ ν λ립λλ€. λκ΅°κ° μ¬μ©μ μ§μ μ€ν¬λ‘€ λ§λλ₯Ό μ¬μ©νμ¬ μ§μ°μ λ¬Έμ κ° μμ΅λκΉ?
ν΄λμ΄? μ΅μ’ ν΄κ²°μ± μ 무μμ λκΉ?
μ΄κ²μ΄ λꡬμκ²λ λμμ΄λλ€λ©΄ OverlayScrollbars μ ν¨κ» μλνλλ‘ κ΄λ¦¬νμ΅λλ€. μ€ν¬λ‘€ μ΄λ²€νΈλ₯Ό ν΄λΉ μμμ μ λ¬νκΈ° λ§νλ©΄λ©λλ€. λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
const Overflow = ({ children, onScroll }) => {
const ofRef = useRef(null);
useEffect(() => {
const el = ofRef.current.osInstance().getElements().viewport;
if (onScroll) el.addEventListener('scroll', onScroll);
return () => {
if (onScroll) el.removeEventListener('scroll', onScroll);
};
}, [onScroll]);
return (
<OverlayScrollbarsComponent
options={options}
ref={ofRef}
>
{children}
</OverlayScrollbarsComponent>
);
};
κ·Έλ° λ€μ κ°μν λ κ΅¬μ± μμμμ :
<FixedSizeGrid
{...props}
outerElementType={Overflow}
>
λλ μ΄κ²μ FixedSizeGrid
μ ν¨κ» μ¬μ©νκ³ μμ§λ§ λͺ©λ‘μ λν΄μλ λμΌνκ² μλν©λλ€.
λμμ΄λκΈ°λ₯Ό λ°λλλ€.
κ°μ₯ μ μ©ν λκΈ
λ λμ λ°©λ²μ
Scrollbars
λ₯ΌouterElementType
μ https://codesandbox.io/s/vmr1l0p463