React-native: [FlatList] ์Šคํฌ๋กคํ•  ๋•Œ๊นŒ์ง€ ํ–‰์ด ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2015๋…„ 07์›” 01์ผ  ยท  223์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/react-native

์•ˆ๋…•ํ•˜์„ธ์š”,
๋ถ€๋ถ„์ ์œผ๋กœ ๋กœ์ปฌ ๋ฐ ๋ถ€๋ถ„์ ์œผ๋กœ ์›๊ฒฉ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋Š” ListView.DataSource์˜ ์ดˆ๊ธฐ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ListView๋ฅผ ๋ž˜ํ•‘ํ•˜๊ณ  ListView์— ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ƒํƒœ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์›๊ฒฉ ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์‹ ๋˜๋ฉด ์ƒˆ ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ cloneWithRowsAndSections ๋ฉ”์„œ๋“œ์— ์˜ํ•ด ๋ณต์ œ๋˜๊ณ  ์‚ฌ์šฉ์ž ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ƒํƒœ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์ด๋ฏธ ํ‘œ์‹œ๋œ ํ–‰๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ณ  ์Šคํฌ๋กค ํ›„์— ์ƒˆ ํ–‰์ด ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

renderbug

๋ฒ„๊ทธ์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ListView๋ฅผ ๊ฐ•์ œ๋กœ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? react-native 0.5์—์„œ๋Š” ์ž‘๋™ํ–ˆ์ง€๋งŒ 0.6์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•œ ํ›„์—๋Š” ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

0.17์—์„œ ์ด์™€ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๋ณด์•˜์ง€๋งŒ removeClippedSubviews ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  223 ๋Œ“๊ธ€

+1
์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. 0.5์—์„œ๋Š” ์ž‘๋™ํ–ˆ์ง€๋งŒ 0.6์—์„œ๋Š” ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ 0.7์—์„œ ์ˆ˜์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜‘๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

cloneWithRows๋Š” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ cloneWithRowsandSections๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

cloneWithRowsandSections๊ฐ€ 0.7์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋ณด์ž…๋‹ˆ๊นŒ?

๋˜ํ•œ initialListSize๋ฅผ ๋” ํฐ ์ˆซ์ž๋กœ ์„ค์ •ํ•˜๋ ค๊ณ  ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” 0.7์—์„œ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ํฐ initialListSize๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์œผ๋ฉฐ 0.7 ๋ฒค๋” ์ข…์†์„ฑ ๋•Œ๋ฌธ์— ์•„์ง ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋” ๋น ๋ฅด์ง€ ์•Š์„ ๊ฒฝ์šฐ ๊ฐ€๋Šฅํ•œ ํ•œ 0.7์— ๋Œ€ํ•ด ์•Œ๋ ค ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. :)

๋ฒ„์ „ 0.6์˜ cloneWithRows์™€ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ 0.5์—์„œ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

0.7์—์„œ๋Š” ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ์ด์ „์— initialListSize๋ฅผ ๋” ๋†’์€ ์ˆซ์ž๋กœ ์„ค์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋„์›€์ด ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

0.7์—์„œ ์ž‘๋™

0.7.1์—์„œ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ

๋ฒ„์ „ 0.7.1์˜ cloneWithRows์™€ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ

๋‚˜๋ฅผ ์œ„ํ•ด ๊ทธ๊ฒƒ์€ 0.7.1์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

0.8.0์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•„์ง ์‚ฌ์šฉ cloneWithRows ๋Œ€์‹  cloneWithRowsAndSections

cloneWithRows ์ด(๊ฐ€) yamill์— ์ ํ•ฉํ•ฉ๋‹ˆ๊นŒ? 0.8.0์—์„œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@coderdave๋Š” ์‹ค์ œ๋กœ cloneWithRows ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ์‹ค์ˆ˜.

@sahrens @ide @michalraska ๋‚ด scrollY ์†Œํ’ˆ์ด ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šคํฌ๋กค ์˜คํ”„์…‹์„ ๊ตฌ์„ฑ ์š”์†Œ์— ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

    renderRow: function (rowData, sectionID, rowID) {
          return (
            <Row
            key={rowData.id} data={rowData} scrollY={this.state.contentOffset}
             />
          )
    });

๊ทธ๋Ÿฌ๋‚˜ ์ด ์ค„์„ ์ˆ˜์ •ํ•˜๋ฉด ๋‚ด ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ scrollY ์†Œํ’ˆ์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์œผ๋กœ ๋‹ค๋ฅธ ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

https://github.com/facebook/react-native/blob/757d6d204ae2d743634af64e3f78a4aad9d53f70/Libraries/CustomComponents/ListView/ListView.js#L342 -L343

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋‹ค์Œ์—์„œ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

var shouldUpdateRow = rowCount >= this.state.prevRenderedRowsCount && dataSource.rowShouldUpdate(sectionIdx, rowIdx);

์—๊ฒŒ

var shouldUpdateRow = true;

0.11.0-rc์—์„œ๋„ ์ด๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

ํ–‰: https://rnplay.org/apps/d3DM6A
ํ–‰ + ์„น์…˜: https://rnplay.org/apps/xnyaYw

๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด๋‚ธ ์ž„์‹œ ํ•ด๊ฒฐ์ฑ…์€ ListView 1pt๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ์Šคํฌ๋กคํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

let listViewScrollView = this.refs.listView.getScrollResponder();
listViewScrollView.scrollTo(1);

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด rnplay.org์˜ ์˜ˆ์ œ ๋‚ด์—์„œ ์ด ์„น์…˜์˜ ์ฃผ์„์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋ฆฌ์„์€ ์งˆ๋ฌธ. ์ด๊ฒƒ์€ NavigatorIOS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ NavigatorIOS์˜ ์ž์‹์œผ๋กœ ๋ Œ๋”๋ง๋  ๋•Œ ๋ Œ๋”๋ง, ํŒจ๋”ฉ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@jaygarcia ์˜ˆ์ œ์—์„œ๋Š” NavigatorIOS๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ NavigatorIOS ๋Œ€์‹  Navigator๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

+1, ํ˜„์žฌ Navigator๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ด ๋™์ž‘์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” 0.11์ด๊ณ  cloneWithRows๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ @christopherdro ์˜ ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์ง€๋งŒ ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด ์ถฉ๋ถ„ํžˆ ์Šคํฌ๋กคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(ํฌ๊ธฐ๊ฐ€ ํผ).

ํฅ๋ฏธ๋กญ๊ฒŒ๋„ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์ด ๋ฒ„๊ทธ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react-native/issues/1878 ๋”ฐ๋ผ์„œ ์ตœ์ข… ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    listViewScrollView.scrollWithoutAnimationTo(80);
    listViewScrollView.scrollWithoutAnimationTo(-80);

์ข‹์•„, ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ๋œ ScrollViews์— ๋ช‡ ๊ฐ€์ง€ ๊ธฐ์ดํ•œ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ›„ ํ•ด๋‹น ๋ณด๊ธฐ์—์„œ ์ดˆ๊ธฐ ์Šคํฌ๋กค ์˜คํ”„์…‹์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹๋ณ€๊ฒฝํ•˜๋Š” onScroll ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ์ „ํžˆ 0.12.0์˜ ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ณด๊ธฐ ๊ณ„์ธต ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

0.11.0์˜ @Sidnicious ์™€ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋‚ด ์•ฑ์—๋Š” ์ดˆ๊ธฐ ๋ฒ„์ „์˜ react-native๋ถ€ํ„ฐ ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. Navigator ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ListView ์ด๋™ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

0.13.0-rc ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

0.13.1 ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    constructor(props) {
        super(props);
        var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.state = {dataSource: ds.cloneWithRows(Array.apply(null, {length: 100}).map(Number.call, Number))};
    }
    render() {
        return (
    <ListView
        style={{paddingTop: 20, flex: 1}}
        dataSource={this.state.dataSource}
        renderRow={(rowData) => <Text>{rowData}</Text>}
    />
    )

์ €์—๊ฒŒ ์ด ๋ฌธ์ œ๋Š” 0.14.2 ์—์„œ 0.16.0-rc ์—…๊ทธ๋ ˆ์ด๋“œํ•  ๋•Œ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ €์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ๋˜ ์ˆ˜์ • ์‚ฌํ•ญ์€ ListView์˜ pageSize ์†Œํ’ˆ์„ 3์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. 2๋Š” ์ €์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์ง€๋งŒ 3์€ ์ž˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

ยฏ_(ใƒ„)_/ยฏ

์—ฌ๊ธฐ์— 0.15.0๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํŠธ๋ฆญ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์šด์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. iOS 9.1 ์•„์ดํฐ 6

@nicklockwood - ์—ฌ๊ธฐ์„œ ๋„์™€์ฃผ์‹ค ์ˆ˜ ์žˆ๋‚˜์š”? ์•„์ง ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

0.14, ๋™์ผํ•œ ๋ฌธ์ œ

์œ ์‚ฌํ•œ LisView ๋ฌธ์ œ ์—ฐ๊ฒฐ: https://github.com/facebook/react-native/issues/4728

๋‹ค๋ฅธ ์œ ์‚ฌํ•œ ๋ฌธ์ œ ์—ฐ๊ฒฐ: https://github.com/facebook/react-native/issues/4179

๋‚˜๋Š” ์ด๊ฒƒ์„ 0.16.0์—์„œ ๋ณด๊ณ  ์žˆ๋‹ค. Product Pains์˜ ๋ ˆ์ด๋”์— ์ด๊ฒƒ์„ ๋ฐฐ์น˜ํ•œ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์ƒ๋‹นํžˆ ๊ณ ํ†ต์Šค๋Ÿฌ์›Œ์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. :/

๋‚˜๋Š” ์ด๊ฒƒ์„ Product Pains ์— ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์—ฌ์ „ํžˆ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ๋‹ค๋ฉด ๊ฑฐ๊ธฐ์— ์ž์œ ๋กญ๊ฒŒ ํˆฌํ‘œํ•˜์‹ญ์‹œ์˜ค.

0.16, ๋™์ผํ•œ ๋ฌธ์ œ

dataSource์—์„œ cloneWithRows๋ฅผ ์‚ฌ์šฉํ•˜๋Š” 0.17์—์„œ๋„ ๋ฌธ์ œ๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ชฉ๋ก์€ ์Šคํฌ๋กค๋  ๋•Œ๋งŒ ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

0.17์—์„œ ์ด์™€ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๋ณด์•˜์ง€๋งŒ removeClippedSubviews ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

+1
0.17์—์„œ ์ด์™€ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๋ณด๊ณ  ์žˆ์—ˆ์ง€๋งŒ removeClippedSubviews๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ๊ทธ๊ฒƒ์€ removeClippedSubviews ์œ ๋ฌด์— ๊ด€๊ณ„์—†์ด 0.17์—์„œ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•Œ์•„์ฐจ๋ฆฐ ๊ฒƒ์€ ๋‚ด ๋ฌธ์ œ๊ฐ€ ์ˆ˜๋™์œผ๋กœ ์„ค์ •๋œ contentOffset ๋ฐ initialListSize ์™€ ๊ด€๋ จ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜คํ”„์…‹์ด initialListSize ๋Œ€ํ•ด ๋ Œ๋”๋ง๋  ์š”์†Œ์˜ ๋†’์ด๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กคํ•  ๋•Œ๊นŒ์ง€ ํ•„์š”ํ•œ ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

flexDirection: 'row' ์„ค์ •๋œ ๋ชฉ๋ก์—๋„ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ์†์„ฑ์„ ์ œ๊ฑฐํ•˜๋ฉด ๋ชจ๋“  ํ•ญ๋ชฉ์ด ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ์„ค์ •๋œ ๊ฒฝ์šฐ ๋ชฉ๋ก์€ ์ฒ˜์Œ์— ๋‘ ํ•ญ๋ชฉ๋งŒ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

Navigator๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ removeClippedSubviews ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ.
๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” https://github.com/machard/react-native-advanced-navigation ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋ณด๊ธฐ๊ฐ€ ์‹ค์ œ๋กœ ํ™”๋ฉด์— ํ‘œ์‹œ๋œ ํ›„ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋˜๊ธฐ ๋•Œ๋ฌธ์ผ ์ˆ˜ ์žˆ์Œ).

contentContainerStyle ์†์„ฑ์— ์„ค์ •๋œ flexDirection: 'row' ๋ฐ flexWrap: 'wrap' ์—๋„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ pageSize ์ž…๋‹ˆ๋‹ค.

๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฒ„์ „: 0.19.0

@jittuu ๊ฐ€ pageSize ์†Œํ’ˆ์„ ์„ค์ •

pageSize๋ฅผ ๋ฌด์—‡์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๊นŒ?

@gre ๋ ˆ์ด์•„์›ƒ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ณด๊ธฐ๊ฐ€ ํ–‰์œผ๋กœ ์ •๋ ฌ๋œ ๊ฒฝ์šฐ pageSize๋Š” ํ–‰๋‹น ํ•ญ๋ชฉ์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ ๊ฐ’์œผ๋กœ ์‹คํ—˜ํ•˜์—ฌ ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ „์ฒด ํ™”๋ฉด์„ ์ฑ„์šธ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ํฌ๊ฒŒ initialListSize๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ปค๋ฐ‹์˜ ์„ค๋ช…์ด ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react-native/commit/e7005f7f5429422b6f2e9c2aa29c9d57bda7b77a

@jittuu ์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค. flexWrap ์‚ฌ์šฉํ•  ๋•Œ๋„ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

@jittuu ๋Š” pageSize๋ฅผ ๊ฐ’ 2๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ชฉ๋ก ๋ณด๊ธฐ์—์„œ ์Šคํฌ๋กค์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์•ฑ์„ ํƒ์ƒ‰ํ•˜๊ณ  ๋Œ์•„๊ฐˆ ๋•Œ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
pageSize๊ฐ€ ๋„์›€์ด ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(1์—์„œ 60๊นŒ์ง€ ๋‹ค๋ฅธ ๊ฐ’์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค).

@gre ๋‹น์‹ ์€ initialListSize๋ฅผ ์ถฉ๋ถ„ํžˆ ํฌ๊ฒŒ ์„ค์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋ณผ ์ˆ˜ ์žˆ๋Š” repo๊ฐ€ โ€‹โ€‹์žˆ์Šต๋‹ˆ๊นŒ?

@jaygarcia @nicklockwood ์ด ๋ฒ„๊ทธ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๋ฐ๋ชจ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. URL: ListNotRender

๋‹จ๊ณ„:

  1. ์•ฑ์„ ์—ฝ๋‹ˆ๋‹ค.
  2. ํƒญ ํ‘œ์‹œ์ค„ ํ•ญ๋ชฉ "#1"์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  3. ์Šคํฌ๋กค ํ•  ๋•Œ๊นŒ์ง€ ๋ชฉ๋ก ํ•ญ๋ชฉ์ด ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ๋ฒ„๊ทธ๊ฐ€ ListView์˜ removeClippedSubviews ์†์„ฑ๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•˜๋ฉฐ ๋ฒ„๊ทธ๋Š” true๋กœ ์„ค์ •๋˜์—ˆ์„ ๋•Œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ RN 0.26.0์—์„œ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ ์ƒํ™ฉ:

  • removeClippedSubviews={true}
  • ListView๊ฐ€ ํ™”๋ฉด ๋ฐ–์—์„œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒํ˜ธ ์ž‘์šฉํ•  ๋•Œ๊นŒ์ง€ ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ๋ฏธ๋„๋Ÿฌ์ง‘๋‹ˆ๋‹ค.

cc @javache

๋‚˜๋Š” ์ด๊ฒƒ์ด https://github.com/facebook/react-native/commit/1fcd73f3841d5afbabfa3adecfb7d4036d91a60e์— ์˜ํ•ด ์ˆ˜์ •๋˜์—ˆ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

@javache ์ˆ˜๋™์œผ๋กœ ํ•ด๋‹น ์ค„์„ ๋กœ์ปฌ์— ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์ด๊ฒƒ์„ https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7 ์œ„์— ์ ์šฉํ–ˆ์ง€๋งŒ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ;)

RN 0.28 ์œ„์— ์žˆ๋Š” ๋‹จ์ผ https://github.com/facebook/react-native/commit/1fcd73f3841d5afbabfa3adecfb7d4036d91a60e ์ปค๋ฐ‹์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋ฒ„๊ทธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.


์ด๊ฒƒ์— ๋Œ€ํ•ด ์กฐ๊ธˆ ์กฐ์‚ฌ ํ•˜๋ฉด ListView๊ฐ€ ๋” ์ด์ƒ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ(์˜ˆ: ์Šคํฌ๋กค ์—…๋ฐ์ดํŠธ ์ค‘) ์—ฌ์ „ํžˆ ์—…๋ฐ์ดํŠธ๋˜๊ณ  ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค

์‚ฌ์‹ค ๋ทฐ์—์„œ ์Šคํฌ๋กคํ•˜๋ฉด ๋ฒ„๊ทธ๋ฅผ ์‰ฝ๊ฒŒ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ 'gravity'๋กœ ์Šคํฌ๋กค๋˜๊ณ  ์žˆ์„ ๋•Œ ํƒ์ƒ‰์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์กฐ๊ธˆ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋’ค๋กœ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ์Šคํฌ๋กค ํ•  ๋•Œ๊นŒ์ง€ ์ „์ฒด ํ™”๋ฉด์€ ํฐ์ƒ‰์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ๋ฒ„๊ทธ๊ฐ€ ๋‚˜์—๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์œ ์ผํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ~ ๋ชจ๋‘์—๊ฒŒ ๋™์ผํ•œ ์žฌํ˜„ ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋ฒ„๊ทธ๊ฐ€ ์ด๋ณด๋‹ค ๋” ๋„“์Šต๋‹ˆ๊นŒ?

๊ทธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” @janmonschke https://github.com/facebook/react-native/issues/1831#issuecomment -22799032 ์—์„œ ๊ทธ๋ฆฌ ๋ฉ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


์ด ๋ฒ„๊ทธ์˜ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ธฐ๋Š” ์–ด๋ ต์ง€๋งŒ ์—ฌ๊ธฐ์— ์ œ 2์„ผํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํ–‰์ด _white_ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. scrollview๋ฅผ ๋‹ค์‹œ ๋ณด์ด๊ฒŒ ํ•  ๋•Œ _(์˜ˆ: ๋’ค๋กœ ์ด๋™)_ ์—ฌ์ „ํžˆ ํฐ์ƒ‰์ด๊ณ  ์ƒˆ๋กœ์šด ์Šคํฌ๋กค์ด ๋ฐœ์ƒํ•  ๋•Œ๊นŒ์ง€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค _(์—…๋ฐ์ดํŠธํ•  ์ด์œ ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ๋จ)_.

ScrollView๊ฐ€ ์—ฌ์ „ํžˆ ๋ณด์ด๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ž์‹( updateClippedSubviews ?)์„ ๋ Œ๋”๋งํ•˜๋ฉด ๋ฒ„๊ทธ๊ฐ€ ์ˆ˜์ •๋ฉ๋‹ˆ๊นŒ? (๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํ–‰์ด ๋ Œ๋”๋ง๋˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์‹œ ํฐ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)

@javache 1fcd73f๋Š” ์ฑ„์šฐ์ง€ ์•Š์€ ํ•˜๋‚˜ ๋˜๋Š” ๋‘ ๊ฐœ์˜ ํ–‰์œผ๋กœ ListView์˜ ๊ฒฝ์šฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ListView๋ฅผ ์Šคํฌ๋กคํ•ด๋„ ๋ชฉ๋ก ํ–‰์„ ๋‹ค์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฒ„๊ทธ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

  1. removeClippedSubViews = true๋กœ ListView๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  2. ํ–‰์„ ํ„ฐ์น˜ํ•˜์—ฌ ๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  3. ํ™”๋ฉด ๋ฐฉํ–ฅ์„ 90๋„ ํšŒ์ „ํ•ฉ๋‹ˆ๋‹ค.
  4. ํ™”๋ฉด์„ ๋’ค๋กœ ํšŒ์ „ํ•ฉ๋‹ˆ๋‹ค.
  5. ListView ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ

ListView๋Š” ๋น„์–ด ์žˆ๊ณ  ํ™”๋ฉด๋ณด๋‹ค ๋งŽ์€ ํ–‰์ด ์žˆ๊ณ  ListView๋ฅผ ์Šคํฌ๋กคํ•˜๋ฉด ํ™”๋ฉด๋ณด๋‹ค ์ž‘์€ ํ–‰์ด ๋‹ค์‹œ ํ‘œ์‹œ๋˜๋ฉฐ ์Šคํฌ๋กค ListView๋Š” ์•„๋ฌด ๊ฒƒ๋„ ๋‹ค์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 1fcd73f ์Šคํฌ๋กค ListView๋กœ ๋‹ค์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค :)

  1. 0.26.3๋ถ€ํ„ฐ ์ด ๋ฌธ์ œ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋จ
  2. ๋‚ด ๋น„ RN ํ”„๋กœ์ ํŠธ์—์„œ ๊ธฐ๋ณธ Android์—์„œ ๋ฌธ์ œ๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์„ ํƒํ•œ ์†”๋ฃจ์…˜์€ scrollTo 1px ์•ž๋’ค๋กœ ์ด๋™์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘์—์„œ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

requestAnimationFrame(() => { this.listview.scrollTo({y: 1}); });

@JBerendes ์˜ˆ ์ด ํ•ดํ‚น์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์‚ฌ์šฉ์ž์˜ ์Šคํฌ๋กค์„ ์†์ƒ์‹œํ‚ค์ง€ ์•Š๋Š” ๋ณด๋‹ค ์ •๊ตํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

class ...YourListAbstraction {

  _scrollY = 0;
  _lastTimeScrolled = 0;

  scrollHackToWorkaroundWhiteBug (amount) { // call at appropriated time, with -1 or 1. if possible alternate so you don't change the actual scroll over calls xD
    const { list } = this.refs;
    if (!list) return;
    if (Date.now() - this._lastTimeScrolled < 500) return; // don't mess with user scroll
    list.getScrollResponder().scrollTo({
      y: this._scrollY + amount,
    });
  }

  onScroll = ({ nativeEvent }) => { // give onScroll={this.onScroll} to ListView
    this._scrollY = nativeEvent.contentOffset.y;
    this._lastTimeScrolled = Date.now();
  };

}

ListView ์ถ”์ƒํ™”์— ๋„ฃ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ ์ ˆํ•œ ์‹œ๊ฐ„์— scrollHackToWorkaroundWhiteBug ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ €์—๊ฒŒ๋Š” ํ™”๋ฉด์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค(์ „ํ™˜ ์ „ํ›„)์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ListView์˜ scrollRenderAheadDistance (ํ„ฐ์น˜๋œ ํ›„ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์€ ํ–‰์„ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์—)์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  scrollRenderAheadDistance ๋ฅผ 1800๋ณด๋‹ค ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. scrollRenderAheadDistance ์™€ ๋ Œ๋”๋ง๋˜๋Š” ํ–‰ ์ˆ˜ ์‚ฌ์ด์—๋Š” ํ™•์‹คํžˆ ์ƒ๊ด€ ๊ด€๊ณ„๊ฐ€ ์žˆ์ง€๋งŒ ์ผ๊ด€์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค(๋•Œ๋กœ๋Š” ๋ชจ๋“  ํ–‰์„ ๋ Œ๋”๋งํ•˜์ง€๋งŒ).

| scrollRenderAheadDistance | ๋ Œ๋”๋ง๋œ ํ–‰ ์ˆ˜ |
| --- | --- |
| 1000 | 2 |
| 1200 | 2-5 |
| 1400 | 5 |
| 1600 | 6 |
| 1800 | 7+ |

80pt ๋†’์ด์˜ ํ–‰์œผ๋กœ ListView๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ListView์— ๋Œ€ํ•ด ์ •ํ™•ํ•œ scrollRenderAheadDistance ๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๊ณต์‹์„ ๋„์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.

scrollRenderAheadDistance = 680 + (ROW_HEIGHT_IN_PIXELS * INITIAL_PAGE_SIZE_IN_PIXELS)

๊ทธ๋Ÿฌ๋‚˜ 680 (๋˜๋Š” 340 * 2 )์˜ ์ค‘์š”์„ฑ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์ด ์†”๋ฃจ์…˜์€ ๋””๋ฒ„๊ทธ์—์„œ ์ž‘๋™ํ•˜์ง€๋งŒ ๋ฆด๋ฆฌ์Šค ์ฒด๊ณ„(iOS์šฉ)์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค...

์ข‹์•„, removeClippedSubviews ๋ฅผ false๋กœ ์„ค์ •ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

0.26์—์„œ 0.29๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ๋•Œ๊นŒ์ง€ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ 0.27, 0.28 ๋˜๋Š” 0.29์— ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์•„์ง 0.27 ๋˜๋Š” 0.28์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋„์›€์ด ๋œ๋‹ค๋ฉด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

@gnestor 0.29์—์„œ ๊นจ์กŒ์Šต๋‹ˆ๋‹ค. #8607 ๋ฐ https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7์„ ํ™•์ธ

@gnestor @nihgwu ๋ฒ„๊ทธ๊ฐ€ ์ตœ๊ทผ ํ‡ดํ–‰์ด ์•„๋‹ˆ๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” 1๋…„ ์ „์— ์ƒ์„ฑ๋˜์—ˆ์œผ๋ฉฐ RN 0.13๋ถ€ํ„ฐ ๊ฐœ์ธ์ ์œผ๋กœ ๊ฒฝํ—˜ํ–ˆ์œผ๋ฉฐ ํ•ญ์ƒ ListView๋กœ "์ƒ์กด"ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. removeClippedSubviews ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ํฐ ๋ชฉ๋ก์ด ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค.
๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ตœ์†Œํ•œ ๋ฒ„๊ทธ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ค„์ด๋ ค๋Š” ์‹œ๋„๊ฐ€ ์žˆ์—ˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์ด ์ดˆ๊ธฐ ๋ฌธ์ œ ๋ฉ”์‹œ์ง€์—์„œ ๋ณด๊ณ ๋œ ๊ฒƒ๊ณผ ๊ฑฐ์˜ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@gre ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ #8607์ด 0.29์— ๋„์ž…๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋นˆ ๋ณด๊ธฐ๋กœ ๊ฐ€๋Š” ๊ฒƒ์€ ์ •๋ง ๋ฒˆ๊ฑฐ๋กœ์šด ์ผ์ž…๋‹ˆ๋‹ค. https://github.com/facebook/react-native/commit/1048e5d3445094393298d4e818ff04c41f4e56a7 ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋˜๋Œ๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. removeClippedSubviews ๋„์ง€ ์•Š๊ณ  ์ „์—

initialListSize ๋ฅผ ์ ์ ˆํ•œ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ณ  removeClippedSubviews ๋ฅผ false๋กœ ์„ค์ •ํ•˜์—ฌ ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์‹ญ์‹œ์˜ค.

0.28์—์„œ 0.29๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•œ ํ›„ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
removeClippedSubviews={false} ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์ œ ๊ฒฝ์šฐ์—๋Š” componentDidUpdate() ์—์„œ ListView height ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
componentDidUpdate() ์˜ ๋†’์ด ์—…๋ฐ์ดํŠธ ์ฝ”๋“œ๋ฅผ setTimeout ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ์ž ์ง€์ • ์‹œ๊ฐ„ ์ œํ•œ์œผ๋กœ ๋ž˜ํ•‘ํ•˜๋Š” ๊ฒƒ๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์ด๊ฒƒ์„ ๊ฒฝํ—˜ํ–ˆ์ง€๋งŒ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋กœ ์ฑ„์›Œ์ง„ ํ•˜๋‚˜์˜ ListView์—์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ iOS์—์„œ๋งŒ ์ด๊ฒƒ์„ ๋ณด์•˜๊ณ  0.29๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„์— ๋งŒ โ€‹โ€‹๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ์˜ ListView๋Š” this.state.dataSource.cloneWithRowsAndSections ํ•˜๊ณ  componentDidMount ๋Š” ๋กœ๋“œํ•  ๋•Œ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ removeClippedSubviews={false} ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

ListView ๊ตฌ์„ฑ ์š”์†Œ์— removeClippedSubviews ๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋„ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ Navigator ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ 0.29 ์˜ Release ์ฒด๊ณ„์—์„œ๋งŒ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. flexDirection: 'row' ๋ฐ flexWrap: 'wrap'์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” RN 0.29.2๋ฅผ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชฉ๋ก ๋ณด๊ธฐ(flexDirection: 'row'๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์€ ๊ณณ)์—์„œ๋Š” ๊ทธ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํฌ์Šคํ„ฐ๊ฐ€ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋น ๋ฅธ ์ˆ˜์ •์€ ์ ์ ˆํ•œ initialListSize ๋ฐ pageSize๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ, ์˜ˆ๋ฅผ ๋“ค์–ด ๋ชฉ๋ก ๋ณด๊ธฐ ์•ˆ์— ์žˆ๋Š” ํ•ญ๋ชฉ ๋ชฉ๋ก์˜ ์ผ๋ถ€๋งŒ ํ‘œ์‹œํ•˜๋Š” ํ•„ํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์•ฑ์˜ ์‘๋‹ต์„ฑ์ด ๋–จ์–ด์งˆ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. , ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ์ „์ฒด ํ‘œ์‹œ ์˜์—ญ์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋ ค๊ณ  ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„ํ„ฐ ์‚ฌ์ด๋ฅผ ํƒญํ•˜๋ฉด ์†๋„๊ฐ€ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ชฉ๋ก ๋ณด๊ธฐ์—์„œ๋Š” initialListSize=0 pageSize=1์„ ์„ค์ •ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ฆฌ๋“œ ๋ชฉ๋ก ๋ณด๊ธฐ์—์„œ๋Š” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(flexDirection: 'row' ๋ฐ flexWrap: 'wrap').

RN v0.31.0-rc.0์—์„œ ์ด๊ฒƒ์„ ์น˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

removeClippedSubviews={false}๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

"removeClippedSubviews={false}"๋Š” ์ข‹์€ ์†”๋ฃจ์…˜์ด ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ–‰์„ ๋ Œ๋”๋งํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. "listView. scrollTo" ๋ฐ "removeClippedSubviews"๋ฅผ ์ œ์™ธํ•œ ๋” ๋‚˜์€ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ๋ฌธ์ œ๋Š” RN 0.31์ด ์žˆ๋Š” ios 10 ๋ฒ ํƒ€์—์„œ ํ›จ์”ฌ ๋” ์‹ฌ๊ฐํ•ฉ๋‹ˆ๋‹ค :-(

removeClippedSubviews ๋Š” Android์—์„œ ๋„์›€์ด ๋˜์ง€ ์•Š์•˜๊ณ  ๋Œ€์‹  ListView ์—์„œ ScrollView ๋กœ ์˜ฎ๊ฒจ์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ •๋ง ์—„์ฒญ๋‚œ ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค. ๋‚˜๋„ ๋งŒ๋‚ฌ๋‹ค.

๋ชจ๋‘๊ฐ€ Product Pains์— ๋Œ€ํ•ด ์ฐฌ์„ฑํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ฒƒ์€ ์ด๋ฏธ ๊ฝค ๋†’์ง€๋งŒ ์•„์ง ๋ˆ„๊ตฐ๊ฐ€์˜ ๋ฐ›์€ ํŽธ์ง€ํ•จ์— ์ฐฉ๋ฅ™ํ•  ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๋†’์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค :-( ์—ฌ๊ธฐ ๋งํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์‹œ์ ์—์„œ ๋‚˜๋Š” ์ด๊ฒƒ์ด ์•„๋งˆ๋„ #8607๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋Œ€์ฒ˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋‚ด ๊ณ„ํš์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

0.33.0 ์— ๊ณ„์† ์กด์žฌ

์—ฌ์ „ํžˆ 0.32์— ์กด์žฌ

์–ด์ œ ์ด ๋ฒ„๊ทธ๋ฅผ ๋งŒ๋‚ฌ๊ณ  removeClippedSubviews = {false} ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

0.33์— +1

์˜ˆ, ์ €๋„ ๊ฐ™์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค! +1
0.33,
ํŽธ์ง‘ํ•˜๋‹ค:
removeClippedSubviews = {false}, ๋‚˜์—๊ฒŒ๋„ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

+1

https://gist.github.com/majak/b0ee1fb6ca725d2cf810d2f0ab394f2e (from #8607) ์ด ํŒจ์น˜๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ์ด ๋ฌธ์ œ์— ๋„์›€์ด ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@majak ์ด ํŒจ์น˜๋ฅผ ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์ ์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ด ๋ฌธ์ œ๋Š” ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค(RN 0.34).

@majak ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ๋„ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค!

์ด๊ฒƒ์€ removeClippedSubviews={true} ์ผ ๋•Œ RN34์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

React Native 0.34์—์„œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋งŒ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',

๋ชฉ๋ก๋ณด๊ธฐ ์Šคํƒ€์ผ์—.

initialListSize={100}
๋‚˜๋ฅผ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ๊ณ ์ณค๋‹ค

@majak ํ•ด๋‹น ํŒจ์น˜๋กœ ํ™๋ณดํ•  ๊ณ„ํš์ด์‹ ๊ฐ€์š”?

@janmonschke ๋„ต ! ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด ์—ฐ๊ฒฐ๋œ ๋ฌธ์ œ๋ฅผ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค.

React Native 0.36์—์„œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด 0.36์—์„œ ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

๋””๋ฒ„๊ทธ ๋ชจ๋“œ์—์„œ๋งŒ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ ์žฅ์น˜์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์€ ์žฅ์น˜์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์œ„์—์„œ ๊ถŒ์žฅํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์œผ๋ฉฐ ListView ์„ ScrollView ๋กœ ๋ฐ”๊พธ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด Android ์žฅ์น˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๋‚ด๋น„๊ฒŒ์ดํ„ฐ๋ฟ์ž…๋‹ˆ๋‹ค. (๋‚ด๋น„๊ฒŒ์ดํ„ฐ ์™ธ๋ถ€์— ๋ชฉ๋ก์„ ๋„ฃ์œผ๋ ค๊ณ  ์‹œ๋„ํ•œ ๊ฒฝ์šฐ์—๋„)
0.37

0.36์—์„œ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ํ•ด๊ฒฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” ์•„์ง๋„ ๊ทธ๊ฒƒ์„ 0.36.1์—์„œ ๋ณด๊ณ  ์žˆ๋‹ค

๋‚˜๋Š” ์•„์ง๋„ ๊ทธ๊ฒƒ์„ 0.36.1์—์„œ ๋ณด๊ณ  ์žˆ๋‹ค

0.31์— ์กด์žฌ
initialListSize={1} ํ•ด๊ฒฐ

React Native 0.38์—์„œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

renderScrollComponent={(props) => <ScrollView style={flex: 1} /> }

์ด๊ฒƒ์€ ๋ฒ„์ „ 0.38์˜ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์—์„œ๋„ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
์ด ์•„์นด์ด๋ธŒ ๋ฒ„์ „ 0.38์˜ ๋ฌธ์ œ, ์ดˆ๊ธฐ ๋ฒ„์ „์—์„œ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” 0.36์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
removeClippedSubviews = {false} ๋ฐ initialListSize={8}์—์„œ ์ž‘๋™ํ•˜๋„๋ก ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

1๋…„์ด ๋„˜์—ˆ๋Š”๋ฐ ์•„์ง๋„ ์ด ์ด์Šˆ๊ฐ€ ์—ด๋ ค์žˆ๋‚˜์š”??

0.39์— ์—ฌ์ „ํžˆ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. removeClippedSubviews = {false} ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

"removeClippedSubviews={false}"๋Š” ์ข‹์€ ์†”๋ฃจ์…˜์ด ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์†”๋ฃจ์…˜์ด ์žˆ๊ณ  ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. ํ”Œ๋žซํผ iOS. RCTView.m ํŒŒ์ผ
screen shot 2017-01-05 at 10 55 30 am
screen shot 2017-01-05 at 10 58 25 am

PR์„ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

RN0.40์—์„œ ํ…Œ์ŠคํŠธํ•œ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? RN0.40์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•œ ํ›„ ๋” ์ด์ƒ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
1, removeClippedSubViews = true๋กœ ListView๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
2, ํ–‰์„ ํ„ฐ์น˜ํ•˜์—ฌ ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์˜ค.
3, ํ™”๋ฉด ๋ฐฉํ–ฅ 90 ํšŒ์ „;
4, ListView ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ;

ListView๋Š” ๋น„์–ด ์žˆ๊ณ  ํ–‰์ด ํ™”๋ฉด๋ณด๋‹ค ๋งŽ์œผ๋ฉด ListView๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

@endpress RN0.41RC0 ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ท€ํ•˜์˜ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ž์ง€๋งŒ ์—ฌ์ „ํžˆ ์žฌํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

0.38์—์„œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ListView์˜ paddingTop์„ 0๊ณผ 1 ์‚ฌ์ด์—์„œ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ListView๊ฐ€ ๋งค๋ฒˆ ์ƒˆ๋กœ ๊ณ ์ณ์ง‘๋‹ˆ๋‹ค.

backgroundColor, ํ…Œ๋‘๋ฆฌ ๋“ฑ์„ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์†์„ฑ์ด ์ž‘๋™ํ•˜๋Š” ๊ฒฝ์šฐ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

@nihgwu๋Š” ์—ฌ์ „ํžˆ

์ด๊ฒƒ์ด ๋ฌธ์ œ๋‹ค
bug-3

@endpress ๋ณ€๊ฒฝ ์‚ฌํ•ญ(https://github.com/facebook/react-native/issues/1831#issuecomment-270552011)์ด ์ œ ๊ฒฝ์šฐ์— ์ ์šฉ๋˜๋ฉฐ facebook/react-native#8607์—๋„ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŒจ์น˜๊ฐ€ ์•„์ง ์™„๋ฒฝํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์—ฌ์ „ํžˆ PR์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋‚˜๋ฅผ ์œ„ํ•ด initialListSize={0}๋ฅผ ์„ค์ •ํ•ด๋„ 0.40.0์œผ๋กœ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค.

@majak ์ด ์น˜๋ช…์ ์ธ ๋ฌธ์ œ์— ์ข‹์€ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๊นŒ?

FlatList๋Š” ์•„์ง ์‹คํ—˜์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ๊ฐ€ ๋” ์ ๊ฑฐ๋‚˜ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ๋ณด์žฅ์€ ์—†์ง€๋งŒ ์œ„ํ—˜์„ ๊ฐ์ˆ˜ํ•˜๊ณ  ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

@sahrens @gre ์ด์ „ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋ก ์ด์ „ ListView์™€ ๋™์ผํ•œ API๋ฅผ ์ œ๊ณตํ•˜๋Š” FlatList ์œ„์— ์ถ”์ƒ ๋ ˆ์ด์–ด๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@sahrens FlatList๋Š” UITableView๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๊นŒ?

FlatList๊ฐ€ ์•ˆ์ •ํ™”๋˜๊ณ  ๋” ์ด์ƒ ์‹คํ—˜์ ์ด์ง€ ์•Š์œผ๋ฉด ListView์™€ ๋™์ผํ•œ API๋กœ ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋‚ด๋ถ€์—์„œ ListView ๊ตฌํ˜„์„ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

UITableView๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ƒˆ๋กœ์šด ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๊ธฐ์กด ๋„ค์ดํ‹ฐ๋ธŒ/ํ”„๋ ˆ์ž„์›Œํฌ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๊ฐ€ ์žˆ๋Š” JS์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๊ตฌํ˜„์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react-native/commit/a3457486e39dc752799b1103ebe606224a8e8d32

@sahrens ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฝค ๋ฉ‹์ง€๊ณ  ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

@savanthongvanh ์ดˆ๊ธฐ ํฌ๊ธฐ๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ ListView์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•˜๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„์ดํ…œ์ด ๋งŽ์œผ๋ฉด ์ฃผ์˜ํ•˜์„ธ์š”.

๋˜ํ•œ ์ด rn 0.41.2๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋‚ด๊ฐ€ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” FlatList์˜ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๊ณง ์†”๋ฃจ์…˜์„ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ์‚ฌ ํ•ด์š”,
๋ก 

FlatList(andVirtualizedList)๋Š” ํ•จ๊ป˜ ํ”Œ๋ ˆ์ดํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋งˆ์Šคํ„ฐ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์„ ์œ„ํ•ด FlatList๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://hackernoon.com/react-native-new-flatlist-component-30db558c7a5b#.xnp03gd2u

initialListSize๋ฅผ ์ ์ ˆํ•œ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ณ  removeClippedSubviews๋ฅผ false๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @hoperce , removeClippedSubviews ๋Š” ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ด๋ฉฐ initialListSize ๋Š” ๊ณ ๋ฅด์ง€ ๋ชปํ•œ ์Šคํฌ๋กค์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

RN .42๊ฐ€ ์žˆ๊ณ  ์—ฌ๊ธฐ์— FlatList์— ๋Œ€ํ•œ ์‹คํ—˜์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด ๋ฌธ์ œ๋กœ (์ž ์‹œ๊ฐ€ ์•„๋‹ˆ๋ผ) ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฒ„์ „์˜ RN์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ํ•ญ์ƒ FlatList ์ฝ”๋“œ๋ฅผ ์•ฑ์— ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FlatList๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ "๋Œ์•„๊ฐˆ ๋•Œ ์ „์ฒด ๋ณด๊ธฐ๊ฐ€ ํฐ์ƒ‰์ด ๋จ" ๋ฒ„๊ทธ๋ฅผ ์—ฌ์ „ํžˆ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ScrollView์™€ ๋” ๊ด€๋ จ์ด ์—†๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์ž ์‹œ ํฐ์ƒ‰์ด ๋˜๋Š” ๋ฌธ์ œ๋Š” FlatList์™€ ์™„์ „ํžˆ ๋‹ค๋ฅด๋ฉฐ ๊ณ ์œ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋น„๋™๊ธฐ ์ฐฝ ๋ Œ๋”๋ง์˜ ๊นŒ๋‹ค๋กœ์šด ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๊ฐ€ ์–ธ๊ธ‰ํ•˜๋Š” ๋ฒ„๊ทธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กคํ•  ๋•Œ๊นŒ์ง€ ์ดˆ๊ธฐ ๋ Œ๋”๋ง์—์„œ ์ฝ˜ํ…์ธ ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์ด๋ฉฐ FlatList๋กœ ์ˆ˜์ •๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

ListView(๋ฐ FlatList)์—์„œ๋„ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ทฐ ์ƒ์„ฑ์ž์—์„œ ๋‚ด ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ []๋กœ ์žฌ์„ค์ •ํ•œ ๋‹ค์Œ setTimeout()์˜ ํ•ญ๋ชฉ ๋ชฉ๋ก์œผ๋กœ ์žฌ์„ค์ •ํ•˜์—ฌ ๋ชฉ๋ก์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฉ๊ธˆ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ๋‚ด ๋ชฉ๋ก ๋ณด๊ธฐ๋Š” TabNavigator์˜ ReactNavigation StackNavigator์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ 1px ์Šคํฌ๋กค์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ํ•ดํ‚น์€ ์—ฌ์ „ํžˆ โ€‹โ€‹ListView/FlatList์—์„œ ๋ชจ๋‘ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜ฌ๋ฐ”๋ฅธ ์ˆ˜๋ช… ์ฃผ๊ธฐ(์ผ๋ฐ˜์ ์œผ๋กœ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„์˜ฌ ๋•Œ)์— ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@gre :

@gre , ์ด์— ๋Œ€ํ•œ ์˜ˆ์ œ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ListView๋ฅผ ํฌํ•จํ•˜๋Š” ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ componentWillMount๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

@ericvicenti - RN์˜ ๋‹ค๋ฅธ ์ฝ”๋“œ ์กฐ๊ฐ์ด ๋งŽ์ด ํ•„์š”ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ˜น์‹œ๋ผ๋„ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋นŒ๋ฆฌ์ง€ ์•Š์„๊นŒ ํ•˜๋Š” ๊ฑฑ์ •์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฝ‘์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ €์žฅ์†Œ์— ๋˜์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ์šฉ๋ฉ๋‹ˆ๊นŒ?

@sahrens ๋ฏธ์•ˆํ•˜์ง€๋งŒ ๋‚ด ํšŒ์‚ฌ ์•ฑ์— ์žˆ์ง€๋งŒ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋นˆ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

@natdm ์œ„์˜ ๋Œ“๊ธ€: https://github.com/facebook/react-native/issues/1831#issuecomment -231069668 โ€“ ์ด๊ฒƒ์ด ๊ธฐ๋ณธ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์Šคํฌ๋กค์ด ์‹œ๊ฐ์ ์œผ๋กœ ๋ˆ„์ ๋˜์ง€ ์•Š๋„๋ก -1px์™€ 1px๋ฅผ ๋ฒˆ๊ฐˆ์•„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. XD ๊ฑฐ๋Œ€ํ•œ ํ•ดํ‚น

SectionList์— ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กคํ•  ๋•Œ๊นŒ์ง€ ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค. @sahrens ๋ˆˆ์— ๋ณด์ด๋Š” ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@smkhalsa ๋ช…ํ™•ํ•œ ์žฌํ˜„์ด ์žˆ์Šต๋‹ˆ๊นŒ? removeClippedSubviews={false}๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๊นŒ?

@sahrens removeClippedSubviews={false}๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์—†์œผ๋ฉด ์ด ํŠน์ • ๋ณด๊ธฐ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค ๋นˆ ํ™”๋ฉด์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ƒˆ๋กœ์šด ์ €์žฅ์†Œ์—์„œ ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๊ฒŒ์‹œํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ €์—๊ฒŒ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค(removeClippedSubviews๋Š” ํ™•์‹คํžˆ ๋ฒ„๊ทธ์˜ ๋ฐฉ์•„์‡ ์ž…๋‹ˆ๋‹ค). react-native-tab-view ๋‚ด๋ถ€์— ๋ชฉ๋ก์ด ์žˆ๋Š” ์•ฑ์—์„œ ์‰ฝ๊ฒŒ ์žฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋” ๊ฐ„๋‹จํ•œ ์˜ˆ๊ฐ€ ๊ทธ๊ฒƒ์„ ์žฌํ˜„ํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

https://github.com/facebook/react-native/issues/1831#issuecomment -228775913์—์„œ ๋‚ด ๋Œ€๋‹ต์˜ ๋งˆ์ง€๋ง‰ ๋‘ ๋‹จ๋ฝ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ทธ ์ฃผ๋ณ€์˜ ๋ฌด์—‡์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค (๋‹จ์ง€ ๊ฐ€์„ค).

(1) ๋ชฉ๋ก์€ '๊ฒฝ๊ณ„ ์ƒ์ž ๋ฐ–์— ์žˆ๊ธฐ' ๋•Œ๋ฌธ์— ๋ฐฐ๊ฒฝ ํƒญ์—์„œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. removeClippedSubviews๋Š” ๋ชฉ๋ก์ด ์—ฌ๊ธฐ์— ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์•„๋ฌด ๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(ํฐ์ƒ‰).
(2) ํƒญ์ด ํฌ์ปค์Šค๋กœ ์ด๋™ํ•˜๊ณ  ํ•ด๋‹น ํƒญ์ด <StaticContainer> ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๊ฒƒ๋„ '์ƒˆ๋กœ ๊ณ ์นจ'๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์—ฌ์ „ํžˆ ํฐ์ƒ‰์ž…๋‹ˆ๋‹ค.
(3) ์‚ฌ์šฉ์ž๊ฐ€ '์Šคํฌ๋กค'ํ•˜๋ฉด ๋ชฉ๋ก ์…€์ด โ€‹โ€‹ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” removeClippedSubviews ๋…ผ๋ฆฌ๋ฅผ ์ƒˆ๋กœ ๊ณ ์น˜๊ณ  ์ƒˆ๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค.

๋ฆฌ๋“œ @gre ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

RN 0.41.2์— ์—ฌ์ „ํžˆ ์กด์žฌํ•˜๊ณ  Android๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ios10๋งŒ ์žˆ์œผ๋ฉด removeClippedSubviews={false}๋กœ ์„ค์ •ํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด listView๋Š” ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ํฐ ๋ฌธ์ œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. tabNavigator(react-navigation)์˜ stackNavigator ๋‚ด๋ถ€์— ์žˆ๋Š” listView.

 render() {
    return (
      <View style={{ flex: 1, justifyContent:'center'}}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this._renderRow.bind(this)}
          removeClippedSubviews={false}
        />
      </View>
    );
  }

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. removeClippedSubviews={false} ์™ธ์—๋Š” ์ถ”๊ฐ€ํ•  ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค.

@agentilela ์ˆ˜์ • ์—ฌ๊ธฐ์—๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

removeClippedSubviews={false} ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ ๋ชจ๊ตญ์–ด๊ฐ€-์ง€๋„์—์„œ์ด ๋ฌธ์ œ๊ฐ€ ์กด์žฌ MapView AFAIK๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ScrollView ํ•˜๊ณ ์™€๋Š” ์•„๋ฌด ์ƒ๊ด€์ด ์—†์Šต๋‹ˆ๋‹ค ListView .

๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ RN44์—์„œ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. initialListSize={200} ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ ํ‘œ์‹œํ•˜๊ธฐ ์ „์— ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ์žฅ๊ธฐ์ ์œผ๋กœ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. 100๊ฐœ ์ด์ƒ์˜ ํ–‰์ด ์žˆ๋Š” ๋ชฉ๋ก ๋ณด๊ธฐ์—์„œ๋Š” ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

ps removeClippedSubViews={false} ๋Š” ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค

removeClippedSubViews={false} ์€(๋Š”) ListView ๋Œ€ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ FlatList ์—๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ListView/FlatList ๋ฐ react-navigation์— ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
TabNavigator ์˜ต์…˜์˜ lazy: true ๋ฐ ListView์˜ removeClippedSubViews={false} ํ–ˆ์Šต๋‹ˆ๋‹ค.

RN 0.44.0์—์„œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ ํƒ์ƒ‰ + TabNavigator + (ListView ๋˜๋Š” FlatList)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
ํƒญ์œผ๋กœ ์ด๋™ํ•˜๋ฉด ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์กฐ๊ธˆ๋งŒ ์Šคํฌ๋กคํ•˜๋ฉด ๋ชฉ๋ก์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ์œ ์ผํ•œ ํƒญ์€ TabNavigator์˜ initialRouteName์— ์žˆ์Šต๋‹ˆ๋‹ค.

์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด lazy: true ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. TabNavigator๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ, removeClippedSubViews๋กœ ์ˆ˜์ •๋จ
์ค‘๋ณต ๋ฌธ์ œ https://github.com/facebook/react-native/issues/14069์— ์„ค๋ช…๋œ ๋Œ€๋กœ
๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด https://github.com/jcharlet/react_native_listview_bug ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋™์ผํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด 'react-navigation' ๋Œ€์‹  'react-native-router-flux'๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

TabNavigator์˜ ๋ฐ˜์‘ ํƒ์ƒ‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. removeClippedSubViews={false}๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €์—๊ฒŒ๋„ ๊ฐ™์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. TabNavigator ๋ฐ StackNavigator๋ฅผ ํ•ด๋‹น ํƒญ์˜ ์ž์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์ผ๋ฐ˜ ListView์™€ ํ•จ๊ป˜ ๋ฐ˜์‘ ํƒ์ƒ‰์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. RN 0.44 / Expo 17, ๊ทธ๋ฆฌ๊ณ  removeClippedSubviews๋„ lazy๋„ ๋„์›€์ด ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค :-/

removeClippedSubviews๋Š” IOS ๋ฒ„์ „์„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์ง€๋งŒ Android์˜ ๊ฒฝ์šฐ initialListSize๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์™€ ํ•จ๊ป˜

"dependencies": {
    "react": "16.0.0-alpha.6",
    "react-native": "0.44.2",
    "react-navigation": "1.0.0-beta.11"
}

๊ทธ๋ฆฌ๊ณ  lazy: true ์—์„œ TabNavigator ์˜ TabNavigatorConfig ๋ชจ๋“  ๊ฒƒ์„ ์ž˜ ๋ Œ๋”๋ง :

const AppNavigator = TabNavigator({
  HomeTab: {
    screen: HomeScreen,
    path: '/'
  },
  PeopleTab: {
    screen: PeopleNavigator,
    path: '/people',
  }
}, {
  lazy: true
});
const PeopleList = ({ people }) => {
  return (
    <FlatList
      data={people}
      renderItem={({item}) => <Text>{item.name}</Text>}
    />
  );
};

๋‹ค์Œ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ
{
"๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ": "0.44.2",
"๋ฐ˜์‘ ํƒ์ƒ‰": "1.0.0-beta.11"
}
๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค. lazy=true๋Š” StackNavigator์— ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
"๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ": "0.44.2",
"๋ฐ˜์‘ ํƒ์ƒ‰": "1.0.0-beta.11"
}
๊ฒŒ์œผ๋ฅธ = ์‚ฌ์‹ค
removeClippedSubViews={๊ฑฐ์ง“}
์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค

์ด๊ฒƒ์€ ์ •๋ง ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ์ด 2๋…„ ๊ฐ„์˜ ๋ฒ„๊ทธ๊ฐ€ ๋งˆ์นจ๋‚ด ์–ธ์ œ ๋‹ซํž์ง€ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” react-native 0.44.2, react-navigation 1.0.0-beta.11๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ๊ณ  ๋ฌธ์ œ์˜ TabNavigator์—์„œ "lazy=true"๋ฅผ ์„ค์ •ํ–ˆ๊ณ  ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ lazy=true๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฏธ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

@jhalborg FlatList & removeClippedSubViews={false}๊ฐ€ ์žˆ๋Š” ๋ชฉ๋ก์˜ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” react-navigation์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ  removeClippedSubViews๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋‹ฌ ์Šคํƒ -> ํ˜„์žฌ ํƒญ ์Šคํƒ -> ํƒ์ƒ‰ ์Šคํƒ์ด ์žˆ๋Š” ์—ฌ๋Ÿฌ ํƒญ ํฌํ•จ

๋‚ด ๋ฌธ์ œ๋Š” ์„ฑ๋Šฅ ๋ถ€์กฑ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ removeClippedSubViews ๊ฐ’์„ ๋งŒ๋“ค์–ด ํ™”๋ฉด ๋กœ๋“œ ์—ฌ๋ถ€์— ๋”ฐ๋ผ on/off๋ฅผ ํ† ๊ธ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํƒญ์— ์žˆ๋Š” ๋™์•ˆ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋Š” ๋ชฉ๋ก์ด ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

constructor (props) {
   super(props)

   this.state = { removeClippedSubViews: false }
} 

componentDidMount () {
  this.setState({ removeClippedSubViews: true })
}

resetData () {
  const callback = (newRecords) => {
    this.setState({ removeClippedSubViews: true, records: newRecords })
  }

  this.setState({ removeClippedSubViews: false, records: [] }, () => {
    someDataHelper.reloadData(callback)
  })
}

render () {
  return (
    <ListView removeClippedSubViews={this.state. removeClippedSubViews} />
  )
}

์ž ์‹œ ๋™์•ˆ ๋‚˜๋ฅผ ๊ท€์ฐฎ๊ฒŒํ–ˆ์ง€๋งŒ ๊ฝค ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜์œผ๋กœ ๋๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์‚ฌ๋žŒ๋“ค์ด ์ง€๊ธˆ FlatList/SectionList๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ListView์—๋Š” ๊ฐœ์„  ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ์Šค๋ ˆ๋“œ์—์„œ ํ•ฉ๋ฆฌ์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์‹๋ณ„๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ƒ๊ฐ?

์ด๊ฑฐ ์ง„์งœ ๋ฒ„๊ทธ ์•„๋‹˜? ๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๊นŒ?

์ด์œ ์— ๋Œ€ํ•ด:

  • FlatList์—์„œ๋„ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ListView๋งŒ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
  • removeClippedSubViews ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ ๋น„์šฉ์ด ์žˆ๋Š” ํ•ดํ‚น์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ํ•ฉ๋ฆฌ์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด FlatList/SectionList ๋‚ด์—์„œ ์—ฌ์ „ํžˆ ํ™œ์„ฑ ๋ฒ„๊ทธ์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

FlatList/SectionList์˜ ์„ฑ๋Šฅ๊ณผ ๊ด€๋ จ๋œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์ด ์•„์ง ListView์—์„œ ์ด๋™ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฉฐ ์ด๋ฏธ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ด์ƒํ•˜๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค.

์œ„์— ๊ฒŒ์‹œํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒƒ์ด ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์— ํ†ตํ•ฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ListView์—์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ?

13727

ListView๊ฐ€ ๋” ๋‚˜์€ ์œ„์น˜์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ListView๋Š” ๊ทธ๋Ÿฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ ์ฐฝ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜ ๊ฐ€์ƒํ™”๋ฅผ ๋Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ„์† ์ง„ํ–‰ํ•˜๊ธฐ ์ „์— ๋ฐฉ๊ธˆ ์งˆ๋ฌธํ•œ ์งˆ๋ฌธ์— ์‘๋‹ตํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์‹ถ์ง€๋งŒ ์š”์ ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ FlatList์—์„œ ๋ฐœ์ƒํ•˜๊ณ  ์—ด๋ ค ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ง€ ์ผ๋ฐ˜์ ์ธ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ง€์‹์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ListView ํ–‰ ๋‚ด์—์„œ Nested ListView, ์ฆ‰ ListView๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์†”๋ฃจ์…˜์€ ์ค‘์ฒฉ๋œ ListView์— removeClippedSubviews={false} ๋ฅผ ์ ์šฉํ•˜์—ฌ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

react-native-cli: 2.0.1
react-native: 0.41.2

iOS 9.x๋ฅผ ์‹คํ–‰ํ•˜๋Š” iPad 3/iPad Mini์™€ ๊ฐ™์€ ์˜ค๋ž˜๋œ ํ•˜๋“œ์›จ์–ด์—์„œ ListView/FlatList/VirtualizedList/WindowedListView(๋ฌด์—‡์ด๋“ )๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฐ ๋ชฉ๋ก์—์„œ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์Šคํฌ๋กคํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ๋‚˜๋Š” ๋‹จ์ˆœํ•œ ๋ชฉ๋ก, ์ด๋ฏธ์ง€๊ฐ€ ์—†๋Š” ํ–‰์˜ ํ…์ŠคํŠธ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๋Š” ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฝ๊ณ  ๊ณ ๋ฅด์ง€ ์•Š์€ 7000๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ ๋ฐ์ดํ„ฐ ์„ธํŠธ์™€ ํ•จ๊ป˜ ๊ธฐ๋Šฅ์  ์˜ˆ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์†์„ฑ ๊ตฌ์„ฑ์„ ์‹œ๋„ํ•˜๊ณ  ์šด์ด ์—†์Šต๋‹ˆ๋‹ค ๐Ÿ˜ข

๋™์˜ํ•จ - ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ณด์ด์ง€ ์•Š๋Š” ์…€๋„ ์ง€์šฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ์•ฑ์—์„œ ์ด๋Ÿฌํ•œ ํ•„์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋งŽ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์„ฑ๋Šฅ์ด ๋„ˆ๋ฌด ๋ถ€์กฑํ•˜๋‹ค๋Š” ๊ฒƒ์€ ๋ถ€๋„๋Ÿฌ์šด ์ผ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ ์ •๋„์— ์ด์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ณ  ์ƒ๋‹นํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

2017๋…„ 6์›” 10์ผ ์˜คํ›„ 3์‹œ 30๋ถ„ +1000, Ariel Falduto [email protected] ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

iOS 9.x๋ฅผ ์‹คํ–‰ํ•˜๋Š” iPad 3/iPad Mini์™€ ๊ฐ™์€ ์˜ค๋ž˜๋œ ํ•˜๋“œ์›จ์–ด์—์„œ ListView/FlatList/VirtualizedList/WindowedListView(๋ฌด์—‡์ด๋“ )๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฐ ๋ชฉ๋ก์—์„œ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์Šคํฌ๋กคํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์ฐธ๊ณ : ๋‚˜๋Š” ๋‹จ์ˆœํ•œ ๋ชฉ๋ก, ์ด๋ฏธ์ง€๊ฐ€ ์—†๋Š” ํ–‰์˜ ํ…์ŠคํŠธ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋ˆ„๊ตฐ๊ฐ€๋Š” ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฝ๊ณ  ๊ณ ๋ฅด์ง€ ์•Š์€ 7000๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ ๋ฐ์ดํ„ฐ ์„ธํŠธ์™€ ํ•จ๊ป˜ ๊ธฐ๋Šฅ์  ์˜ˆ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์†์„ฑ ๊ตฌ์„ฑ์„ ์‹œ๋„ํ•˜๊ณ  ์šด์ด ์—†์Šต๋‹ˆ๋‹ค ๐Ÿ˜ข
โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ๋ณด๊ฑฐ๋‚˜ ์Šค๋ ˆ๋“œ๋ฅผ ์Œ์†Œ๊ฑฐํ•˜์„ธ์š”.

๋ฉ‹์ง„ @lprhodes , ์—ฌ๊ธฐ์—์„œ ~ 200๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” FlatList๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ๋Š” iOS 9๊ฐ€ ์„ค์น˜๋œ iPad 3์—์„œ ๊ณ ๋ฅด์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

import React, { Component } from 'react';
import {
  FlatList,
  StyleSheet,
  View,
} from 'react-native';
import Expo from 'expo';
import {
  Text,
  ListItem,
  SearchBar,
} from 'react-native-elements';

class Feed extends Component {

  loadFeed() {
    const {data} = this.props;
    const sections = [];
    data.forEach((value, index) => {
      const sectionName = value.name_line_sp;
      const section = sections.find((section) => {
        return section.title === sectionName;
      });
      if (section) {
        section.data.push(value);
      } else {
        sections.push({
          title: sectionName,
          data: [value]
        });
      }
    });
    if (__DEV__) {
      console.log('Sections size', sections.length);
    }
    return sections[0];
  }

  componentDidMount() {
    this.flatListRef.scrollToOffset({
      animated: false,
      offset: 48
    });
  }

  render() {
    const feed = this.loadFeed();
    return (
      <View style={{flex: 1}}>
        <Text h5 style={styles.section_title}>{feed.title} ({feed. data.length})</Text>
        <FlatList
          style={{flex: 1}}
          ref={(list) => { this.flatListRef = list; }}
          debug
          ListHeaderComponent={() => (
            <SearchBar
              lightTheme
              placeholder='Search...' />
          )}
          data={feed.data} // ~217 records
          keyExtractor={(item) => (
            item.code_group
          )}
          renderItem={({ item }) => {
            return (
              <ListItem
                hideChevron
                key={item.code_group}
                title={`${item.name_group_sp}`}
                subtitle={`${item.price_prod}`}
                containerStyle={{ backgroundColor: 'white' }}
              />
            );
          }}
        />
      </View>
    )
  }
}

import catalog from './data/catalog.json'; 

class App extends Component {
  render() {
    const data = catalog;
    return (
      <View style={styles.container}>
        <Text h3 style={styles.title}>Skillcase</Text>
        <Feed data={data} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  title: {
    margin: 20,
    marginBottom: 10,
    color: 'white'
  },
  section_title: {
    padding: 20,
    color: 'white',
    backgroundColor: '#1976D2',
  },
  container: {
    flex: 1,
    paddingTop: Expo.Constants.statusBarHeight,
    backgroundColor: '#42A5F5',
  },
});

Expo.registerRootComponent(App);

๋˜๋Š” ์—‘์Šคํฌ uri: exp://8v-xvw.outatime.skillcase.exp.direct :80

๊ฐ์‚ฌ ํ•ด์š” !!!

์˜ˆ์ œ ์ฝ”๋“œ์—๋Š” ๋ฌธ์„œ์—์„œ ํ•ด๊ฒฐ๋œ ๋งŽ์€ ๋‚˜์œ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ง€์†์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค๊ณ  ๋‹ค์‹œ ๋ฐ”์ธ๋”ฉํ•˜๋ฉด CPU์— ๋ถ€๋‹ด์ด ๋˜๊ณ  ๋ชฉ๋ก ํ•ญ๋ชฉ์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ListItem ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ PureComponent์ธ์ง€ ํ™•์ธํ•˜๊ณ  ์—ฌ๊ธฐ์— ์ „๋‹ฌ๋œ ๋ชจ๋“  ์†Œํ’ˆ์ด ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์–•๊ฒŒ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—๋„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋งŽ์€ ๋„์›€์ด ๋  ๊ฒƒ์ด์ง€๋งŒ ๋Š๋ฆฐ ์žฅ์น˜์—์„œ ์™„๋ฒฝํ•œ ์„ฑ๋Šฅ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์•ฑ์ด ํ•ด๋‹น ์žฅ์น˜์—์„œ ์–ผ๋งˆ๋‚˜ ๋” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

@outaTiME ๋˜ํ•œ ๊ฐ ๋ Œ๋”๋ง์—์„œ loadFeed๋ฅผ ํ˜ธ์ถœํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

@lprhodes ๋ Œ๋” ๋ฉ”์„œ๋“œ๋Š” ํ•˜๋‚˜๋งŒ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. btw ์ผ๋ถ€ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  iOS 9๊ฐ€ ์„ค์น˜๋œ iPad 3์—์„œ ์—ฌ์ „ํžˆ ๊ณ ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค(iPhone 7์—์„œ๋Š” ๋ชจ๋‘ ์›ํ™œํ•จ). @sahrens์—์„œ ๊ณ„์† ์ž˜๋ชป๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์กฐ์–ธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

import React, { Component, PureComponent } from 'react';
import {
  FlatList,
  ListView,
  Text,
  StyleSheet,
  View,
} from 'react-native';
import Expo from 'expo';
import {
  ListItem,
  SearchBar,
} from 'react-native-elements';

class FeedRow extends PureComponent {

  render() {
    const item = this.props.data;
    return (
      <Text>{item.name_group_sp}</Text>
    )
  }

}

class Feed extends Component {

  constructor(props) {
    super(props);
    this.storeListRef = this.storeListRef.bind(this);
  }

  loadFeed() {
    const {data} = this.props;
    const sections = [];
    data.forEach((value, index) => {
      const sectionName = value.name_line_sp;
      const section = sections.find((section) => {
        return section.title === sectionName;
      });
      if (section) {
        section.data.push(value);
      } else {
        sections.push({
          title: sectionName,
          data: [value]
        });
      }
    });
    if (__DEV__) {
      console.log('Sections size', sections.length /*, images.length */);
    }
    return sections[0];
  }

  componentDidMount() {
    this.flatListRef.scrollToOffset({
      animated: false,
      offset: 48
    });
  }

  renderItem(item) {
    return (
      <FeedRow data={item.item} />
    );

  }

  keyExtractor(item) {
    return item.code_group;
  }

  listHeaderComponent() {
    return (
      <SearchBar
        lightTheme
        placeholder='Buscar...' />
    );
  }

  storeListRef(list) {
    this.flatListRef = list;
  }

  render() {
    const feed = this.loadFeed();
    return (
      <View style={{flex: 1}}>
        <Text h5 style={styles.section_title}>{feed.title} ({feed. data.length})</Text>
        <FlatList
          style={{flex: 1}}
          ref={this.storeListRef}
          debug
          // pagingEnabled
          ListHeaderComponent={this.listHeaderComponent}
          data={feed.data} // ~217 records
          keyExtractor={this.keyExtractor}
          renderItem={this.renderItem}
        />
      </View>
    )
  }

}

import catalog from './data/catalog.json';

class App extends Component {

  render() {
    const data = catalog;
    return (
      <View style={styles.container}>
        <Text h3 style={styles.title}>Skillcase</Text>
        <Feed data={data} />
      </View>
    );
  }

}

const styles = StyleSheet.create({
  title: {
    margin: 20,
    marginBottom: 10,
    color: 'white'
  },
  section_title: {
    padding: 20,
    color: 'white',
    backgroundColor: '#1976D2',
  },
  container: {
    flex: 1,
    paddingTop: Expo.Constants.statusBarHeight,
    backgroundColor: '#42A5F5',
  },
});

Expo.registerRootComponent(App);

๋” ์ข‹์ง€๋งŒ debug ๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ž‘์—… ์†๋„๊ฐ€ ํฌ๊ฒŒ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ์„ฑ๋Šฅ์„ ํ‰๊ฐ€ํ•  ๋•Œ ๊ฐœ๋ฐœ/๋””๋ฒ„๊ทธ ๋นŒ๋“œ๊ฐ€ ์•„๋‹Œ ์ตœ์ ํ™”๋œ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ์—ฌ์ „ํžˆ ์ƒˆ๋กœ์šด ์Šคํƒ€์ผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์œผ๋ฉฐ onMount์—์„œ scrollToOffset์„ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  initialScrollPosition์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@sahrens yup debug ํ”Œ๋ž˜๊ทธ๊ฐ€ ์—†๊ณ  ์ตœ์ ํ™”๋œ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๋œ ๊ณ ๋ฅด์ง€ ์•Š๊ฒŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ 0.44๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์—‘์Šคํฌ 17์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋งํ–ˆ๋“ฏ์ด, ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ(0.45 ) FlatList ์— ๋Œ€ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

btw, ์™œ ๋ชจ๋“  ๋ Œ๋”๋ง์—์„œ ์Šคํƒ€์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๊นŒ? ์ด ๊ฒฝ์šฐ flex ์Šคํƒ€์ผ์˜ ๋ Œ๋”๋ง( Feed ๊ตฌ์„ฑ ์š”์†Œ์—์„œ)์€ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. App ๋ Œ๋”๋ง
  2. Feed ๋ Œ๋”๋ง
  3. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์—ฌ๋Ÿฌ FeedRow ๋ Œ๋”๋ง

@lprhodes ๊ฐ ๋ Œ๋”๋ง์— loadFeed์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐ ๊ฒƒ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•œ, ๋‚˜๋Š” ์ดํ•ด Feed ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€, ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค ๋ Œ๋”๋ง?

initialScrollPosition ํ•˜๋ฉด initialScrollIndex ์ด๊ฒ ์ฃ ? scrollToOffset ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Feed ๋งˆ์šดํŠธ๋  ๋•Œ ListHeaderComponent (๋†’์ด 48ํ”ฝ์…€)์„ ์ˆจ๊ฒจ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ฝ˜์†” ๊ฒฝ๊ณ ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” renderItem์— PureComponent๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. {"dt":85588,"prevDt":1497296394821,"contentLength":10023}

๊ฐ์‚ฌ ํ•ด์š” !!

๊ทธ ๊ฒฝ๊ณ ๋Š” ๋งˆ์Šคํ„ฐ์—์„œ ์ˆ˜์ •๋œ ์ผ์ข…์˜ ๋ฒ„๊ทธ์ด์ง€๋งŒ ์ดˆ๊ธฐ ๋งˆ์šดํŠธ์˜ ๊ฒฝ์šฐ 85์ดˆ๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋” ๊นŠ์ด ํŒŒ๊ณ ๋“ค์–ด ๋ฌด์—‡์ด ๊ทธ๋ ‡๊ฒŒ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š”์ง€ ์•Œ์•„๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๊ธ€์—์„œ ๋ฐ˜์‘ ์„ฑ๋Šฅ์— ๋Œ€ํ•ด ๊ฒ€์ƒ‰ํ•˜๊ฑฐ๋‚˜ ๊ด‘๋ฒ”์œ„ํ•œ React ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋„์›€์„ ์š”์ฒญํ•˜๋ฉด ๋งŽ์€ ๋ฆฌ์†Œ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์˜ˆ, initialScrollIndex . ์ž‘๋™ํ•˜๋ ค๋ฉด getItemLayout ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ListHeaderComponent ๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ @sahrens , ๋‚˜๋Š” iPad 3 ๋˜๋Š” OS ๋ฒ„์ „ iOS 9์™€ ๊ฐ™์€ ์˜ค๋ž˜๋œ ํ•˜๋“œ์›จ์–ด์— ๋Œ€ํ•ด ๋‘๋ ค์›Œํ•ฉ๋‹ˆ๋‹ค ... ์ตœ์‹  ์žฅ์น˜์—์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ํ•˜๋“œ์›จ์–ด ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค ... ์ž ์‹œ ํ›„ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋” ๊นŠ์€ ๋‚ด์šฉ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋„๋ก ์š”์ฒญํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!!!

์•ˆ๋…• ๊ด‘์‚ฐ์€ ํ”Œ๋žซ ๋ชฉ๋ก์— style={{ backgroundColor: 'white' }} ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@hramos & @sahrens , 0.44.0 ์‚ฌ์šฉ react-native-tab-vew , ๊ทธ๋ฆฌ๊ณ  ์ •๋ง ํ•ต์‹ฌ ํŒ€์€์ด ์‹œ๊ฐ„์— ์ถ”์ฒœ ๋ฌด์—‡ ๋ถ„๋ช…ํ•˜์ง€ ์•Š๋‹ค.

@sjmueller ๋Š” @sahrens ๊ฐ€ ์ด๊ฒƒ์ด ์ด๋ฏธ ๋งˆ์Šคํ„ฐ์—์„œ ์ˆ˜์ •

@hramos ๋ฐฉ๊ธˆ ์ด ์ „์ฒด ์Šค๋ ˆ๋“œ๋ฅผ ๋‹ค์‹œ ๊ฒ€ํ† ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋†“์ณค์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ @sahrens ์—์„œ FlatList๊ฐ€ ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด ๋งˆ์Šคํ„ฐ์— ๊ณ ์ •๋˜์–ด ์žˆ๋‹ค๋Š” ์–ธ๊ธ‰์„ ๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ๋ฌธ์ œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ปค๋ฐ‹/PR๋„ ๋ณด์ง€ ๋ชปํ–ˆ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ถŒ์žฅ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๋„ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

@yaronlevi ๋Š” react-native-tab-view ๋˜๋Š” TabNavigator lazy={true} ์„ค์ •์„ ๊ถŒ์žฅํ•˜์ง€๋งŒ ์ด๋Š” iPhone 7 ํ”Œ๋Ÿฌ์Šค์—์„œ๋„ ๊ธ‰๊ฒฉํ•œ ์ง€์—ฐ์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

@knappdev์— ๋”ฐ๋ฅด๋ฉด lazy ์—†์ด ์ž‘๋™ํ•˜๋ฏ€๋กœ 0.44.0์—์„œ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ํ”Œ๋žซ๋ฆฌ์ŠคํŠธ๊ฐ€ ์‚ฌ์šฉ ์ค‘์ธ์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ removeClippedSubviews๋ฅผ ์ผœ๊ณ  ๋„๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  constructor (props) {
    super(props)

    this.state = { removeClippedSubviews: false }

    this._disableRemoveClippedSubviews = this._disableRemoveClippedSubviews.bind(this)
    this._onViewableItemsChanged = this._onViewableItemsChanged.bind(this)
    this._renderItem = this._renderItem.bind(this)
  }

  _disableRemoveClippedSubviews () {
    this.setState({ removeClippedSubviews: false })
  }

  _onViewableItemsChanged({ viewableItems, changed }) {
    if (!this.state.removeClippedSubviews) this.setState({ removeClippedSubviews: true })
    if (this._disableRemoveClippedSubviewsTimeout) clearTimeout(this._disableRemoveClippedSubviewsTimeout)
    this._disableRemoveClippedSubviewsTimeout = setTimeout(this._disableRemoveClippedSubviews, 3000)
  }

  render () {    
    const { removeClippedSubviews } = this.state

    return (
      <FlatList
        renderItem={this._renderItem}
        removeClippedSubviews={removeClippedSubviews}
        onViewableItemsChanged={this. _onViewableItemsChanged}
      />
    )
  }

removeClippedSubviews๋Š” ์ด์ œ FlatList์— ๋Œ€ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๊บผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Š๋ฆฐ ์žฅ์น˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•ด RNTester ์•ฑ FlatListExample์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ?

FlatListExample์˜ ์„ฑ๋Šฅ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

removeClippedSubviews๋Š” ์ด์ œ FlatList์— ๋Œ€ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๊บผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ - ๊ทธ๋ž˜์„œ ์‹ค์ œ๋กœ ์Šคํฌ๋กคํ•  ๋•Œ ์ผœ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๋ฌด์ž‘์œ„ ์ง€ํ„ฐ๋ฅผ ๋œ ์–ป์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ FlatList๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์ด ์—ฟ๋“ฃ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋ทฐ ์…€์—์„œ ๋ฉ€๋ฆฌ ๋–จ์–ด์ง„ ์…€์„ ๋นˆ ์…€๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ removeClippedSubviews={false} ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ ์— ๊ณ ์น  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๊นŒ? ์„ฑ๋Šฅ์ด ๋„ˆ๋ฌด ๋น„์‹ธ๋”๋ผ๋„?

๋‚˜๋ฅผ์œ„ํ•œ ์ˆ˜์ •์€ ios ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ์›๊ฒฉ์œผ๋กœ js ๋””๋ฒ„๊น…์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๋‹ค.

lazy: true ์„ค์ •์ด ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„์ง ์„ฑ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ removeClippedSubViews={false}

์ตœ๊ณ ์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
๋ชจ๋“  ํ•˜๋“œ์›จ์–ด/์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. removeClippedSubViews={false} ๊ฐ€ iPhone 7์—์„œ ํ•ญ์ƒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

๋ชฉ๋ก ๋ณด๊ธฐ์—์„œ ๊ฐ•์ œ๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

componentDidMount() {
   requestAnimationFrame(() => {
      // HACK TO RELOAD DATA
      this.refs._list.scrollTo({x: 1, y: 0, animated: false})
    });
}

์ฐธ์กฐ์˜ ์˜ˆ.

 <ListView
     ref="_list"
     dataSource={this.state.dataSource}
     renderRow={(data, sectionId, rowId) => <Row
        rowId={rowId}
        selectedRow={this.state.selectedRow}
        onPressRow={this._pressRow.bind(this)}
        {...data}/>}
     renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
     removeClippedSubViews={false}
     initialListSize={SortedBrandList.count}/>

๋ฌธ์ œ๋Š” ์ด๋ฏธ ๋งˆ์šดํŠธ๋˜์—ˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

2017๋…„ 8์›” 24์ผ ์˜คํ›„ 3์‹œ 44๋ถ„์— Peter Suwara [email protected] ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
๋ชจ๋“  ํ•˜๋“œ์›จ์–ด/์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

'''componentDidMount() {
์š”์ฒญ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ”„๋ ˆ์ž„(() => {
// ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋Š” ํ•ดํ‚น
this.refs._list.scrollTo({x: 1, y: 0, ์• ๋‹ˆ๋ฉ”์ด์…˜: false})
});
}'''

'''
์ฐธ์กฐ="_list"
dataSource={this.state.dataSource}
renderRow={(๋ฐ์ดํ„ฐ, ์„น์…˜ ID, ํ–‰ ID) => }
renderSeparator={(sectionId, rowId) => }
removeClippedSubViews={๊ฑฐ์ง“}
initialListSize={SortedBrandList.count}
/>'''

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ๋ณด๊ฑฐ๋‚˜ ์Šค๋ ˆ๋“œ๋ฅผ ์Œ์†Œ๊ฑฐํ•˜์„ธ์š”.

๋‚˜๋Š” ์ ์–ด๋„ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

<ListView removeClippedSubViews={false} .... />

๋‚ด ์ƒ๊ฐ์—๋Š” ClippedSubviews๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฃจํ‹ด์ด ListView๊ฐ€ ํ˜„์žฌ ํ™”๋ฉด์— ์—†์„ ๋•Œ ๊ฒฝ๊ณ„๋ฅผ ์ œ๋Œ€๋กœ ํ™•์ธํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ™”๋ฉด ๋ฐ–์—์„œ ๋ Œ๋”๋งํ•œ ๋‹ค์Œ ํ™”๋ฉด์—์„œ ์›€์ง์ด๋Š” ๋ชจ๋“  ListView ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๋งค์šฐ ์ž์ฃผ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ˆ˜์ •ํ•˜๊ธฐ์— ๋„ˆ๋ฌด ์–ด๋ ค์šด ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์ด ๋ฌธ์ œ๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค: https://github.com/facebook/react-native/blob/master/React/Views/RCTView.m#L321 -L369

๋‚ด ์ƒ๊ฐ์— ์ธก์ •ํ•˜๋Š” ์ขŒํ‘œ ๊ณต๊ฐ„์ด ์ž˜๋ชป๋œ ๊ณณ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ๊ทธ๊ฒƒ์„๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ˆ˜์ •์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? https://github.com/facebook/react-native/pull/15669/files

์•„์ง ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์—†๋‚˜์š”?

@petersuwara : ๋‹น์‹ ์ด ์ œ์•ˆํ•œ ์ž‘์—…. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. @MattFoley : ์ˆ˜์ • ์‚ฌํ•ญ์„ ์–ธ์ œ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

To FlatList์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ  ListView์—์„œ๋„ ๋กœ๋“œํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์„ค์ •ํ•  ๋•Œ ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

componentWillMount ๋ฉ”์„œ๋“œ์—์„œ ์›๊ฒฉ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋ฉด ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค :

setTimeout(function(){
       this.updateDataSource(array,newArray)
},30)

updateDataSource = (comments,dataSource) =>{
        this.setState({
            allComments:comments,
            dataSource: this.state.dataSource.cloneWithRows(dataSource),
            isLoading:false

        })
}

๊ทธ๋ฆฌ๊ณ  ์•ฝ๊ฐ„์˜ ์ง€์—ฐ ์‹œ๊ฐ„ ๋™์•ˆ ํ•ญ์ƒ ๋กœ๋”ฉ ํ™”๋ฉด์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ์งง์•„์„œ ๋ณด์ด์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค.

@nathvarun ์˜ ๋ฐฉ๋ฒ•์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ์ฐพ์•˜

์ด๊ฒƒ์€ react-navigation์˜ ํƒญ์— ํ• ๋‹น๋œ ํ™”๋ฉด๊ณผ ๊ฐ™์ด ์ด๋ฏธ ๋งˆ์šดํŠธ๋œ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋” ํ˜„์žฌ ์„ ํƒ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด PR์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๊ฒƒ ๊ฐ™์ง€๋งŒ ๋ณ‘ํ•ฉํ•˜๋Š” ๋ฐ ์šด์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๊ทธ PR์— ๋Œ€ํ•ด ์ฐจ์ž„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๊นŒ?

@MattFoley ๋ณ‘ํ•ฉ ์—ฌ๋ถ€. ๋‚˜๋Š” ์ง€๊ธˆ ๋‹น์‹ ์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์ •๋ง๋กœ ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

react-navigation ์˜ TabNavigator ๋ฅผ react-navigation lazy: true ๊ฒƒ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค... ํ•˜์ง€๋งŒ react-native ์ˆ˜์ •๋˜๋Š” ๊ฒƒ์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

SectionList ๋˜๋Š” Flatlist๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ref = {(ref)=> this.sectionList = ref }
์ฝ”๋“œ์—์„œ this.sectionList.recordInteraction() - ๋ทฐ๋ฅผ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@MattFoley ์˜ ์ œ์•ˆ๋œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ๋ณ‘ํ•ฉ๋˜์—ˆ์œผ๋ฉฐ ์ด์ œ 0.50 ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. https://github.com/facebook/react-native/commit/03ae65bc25185fe6d7f62e66f5575ced5c3e8378

๋ฐฉ๊ธˆ ์—…๋ฐ์ดํŠธํ–ˆ๋Š”๋ฐ <ListView /> ์—์„œ ์ด ๋ฌธ์ œ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด package.json์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  "dependencies": {
    "native-base": "^2.3.1",
    "react": "^16.0.0",
    "react-native": "^0.50.0-rc.1",
    "react-native-linear-gradient": "^2.3.0",
    "react-native-modal": "^4.1.0",
    "react-native-simple-store": "^1.3.0",
    "react-navigation": "^1.0.0-beta.11"
  },

ListView ๋Š” ์ง€๊ธˆ์ฏค ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. FlatList ์‹œ๋„ํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ 0.50.3์—์„œ ์ด๊ฒƒ์„ ๊ณ„์† ๋ณด๊ณ  ์žˆ๋‹ค๊ณ  ๋ฏฟ๋Š”๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

FlatList๋กœ ์ „ํ™˜ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
2017๋…„ 11์›” 17์ผ ๊ธˆ์š”์ผ ์˜ค์ „ 8:39 Colin Ramsay [email protected]
์ผ๋‹ค:

๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ 0.50.3์—์„œ ์ด๊ฒƒ์„ ๊ณ„์† ๋ณด๊ณ  ์žˆ๋‹ค๊ณ  ๋ฏฟ๋Š”๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/facebook/react-native/issues/1831#issuecomment-345294840 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAZnGZ9oz7uKXx-wz3KFg-FSIzejAfM6ks5s3bavgaJpZM4FP1nt
.

์•„, ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ FlatList๋ฅผ _์‚ฌ์šฉ_ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹0.50.3์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. removeClippedSubviews๋Š” ํšจ๊ณผ๊ฐ€ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

0.50.3์—์„œ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฑฐ ๋‹ค์‹œ ์—ด์–ด์ฃผ์„ธ์š”.

๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค๋งŒ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ด๊ฒƒ์€ ์‹œ๊ธ‰ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ตœ์‹  Expo React Native SDK๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค์Šต๋‹ˆ๋‹ค. TabNavigator์˜ ์„ธ ๋ฒˆ์งธ ListView์—๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ์™€ ์„ธ ๋ฒˆ์งธ ํŽ˜์ด์ง€๋ฅผ ๋ฐ”๊พธ๋ฉด ์ƒˆ ์„ธ ๋ฒˆ์งธ ํŽ˜์ด์ง€๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. removeClippedSubviews๋Š” ์ œ ๊ฒฝ์šฐ์—๋Š” ๊ทธ๊ฒƒ์„ ๊ณ ์ณค์Šต๋‹ˆ๋‹ค.

requestAnimationFrame(() => { this.listview.scrollTo({y: 1}); }); ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

this.listView.scrollToEnd() ์‚ฌ์šฉํ•˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ชฉ๋ก ๋์˜ ์ขŒํ‘œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๊ณ„์‚ฐํ•˜์—ฌ scrollTo() ์ „๋‹ฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

flatlist์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ๋ฐฐ์—ด์„ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. FlatList๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ถˆ๋ณ€ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

removeClippedSubviews={false}๋Š” ์ œ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

<ListView
            data={this.state.mockData}
            renderRow={(rowData) => this.renderRow(rowData)}
            removeClippedSubviews={false}
 />

@edmengel ๋งž์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ ์ผํ•˜๊ณ  ์žˆ์—ˆ๊ณ  ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฒ„๊ทธ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋กคํ•˜๊ธฐ ์ „์—:
screen shot 2018-03-10 at 05 44 59

์Šคํฌ๋กค ํ›„:
screen shot 2018-03-10 at 05 48 29

React-native-router-flux@^4.0.0-beta.27 ๋Š” ํƒ์ƒ‰์— ์‚ฌ์šฉ๋˜๋ฉฐ App.js๋Š” ์ด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€์— ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ด ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ธ ๋ฒˆ์งธ ํƒญ์— ์žˆ์Šต๋‹ˆ๋‹ค.

<Provider store={store}>
        <View style={{flex: 1}}>
            <Router hideNavBar={true}>
                <Scene key="modal" modal>
                    {/* Tab Container */}
                    <Scene key="tabbar" tabs={true} tabBarPosition="bottom" tabBarStyle={{borderTopColor:'black', borderTopWidth:1,backgroundColor:'white'}}>
                      {/*Tabs */}
                        <Scene key="NewPage" component={NewPage} title="NewPage" icon={TabIcon}  hideNavBar={true} />
                        <Scene key="NewPage2" component={NewPage2} title="Newpage2" icon={TabIcon}  hideNavBar={true} />
                        <Scene key="SearchPage" component={SearchPage} title="Search"  hideNavBar={true} />
                    </Scene>
                </Scene>
            </Router>
        </View>
</Provider>

๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ํฌํ•จ๋œ ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€๋ฅผ ์„ธ ๋ฒˆ์งธ ํƒญ์—์„œ ๋‘ ๋ฒˆ์งธ ํƒญ์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ์„ ๋•Œ ๋ชฉ๋ก ๋ณด๊ธฐ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•˜๋Š” Hack์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

render() {
       setTimeout(() => {
            this.sectionList && this.sectionList.recordInteraction(); 
        }, 50);
        return (
            <SectionList ref={(view) => { this.sectionList = view }} />
        )
}

<Flatlist style={{ flex: 1 }}/>
์ด ํŠธ๋ฆญ์€ ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

ScrollView ๋ฐ ListView ๋ชจ๋‘ 0.55.4 ์— ๋Œ€ํ•œ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. removeClippedSubviews={false} ์ถ”๊ฐ€ํ•˜๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ Android https://github.com/facebook/react-native/issues/13600#issuecomment -315629140์—์„œ ๋ˆ„๋ฝ๋œ ์ด๋ฏธ์ง€๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋ Œ๋”๋ง ์‹œ ์•ž๋’ค๋กœ ์Šคํฌ๋กคํ•˜๋Š” ๊ฒƒ์€ ํƒ์ƒ‰ ํ›„์—๋งŒ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ฒ˜์Œ์—๋Š” ๋นˆ ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋ณด๊ธฐ๋ฅผ ์กฐ์ •ํ•˜๋Š” ๊ฒƒ๋„ ๋„์›€์ด ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

ํŠน์ • ์Šคํฌ๋กค ์œ„์น˜ ์ดํ›„์—๋งŒ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค...
https://streamable.com/l5arv

chrome-devtools๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด๊ธฐ๋ฅผ ๊ฒ€์‚ฌํ•˜๋ฉด ๋ชจ๋“  ํ•˜์œ„ ๋ณด๊ธฐ๊ฐ€ ์ž˜๋ฆฐ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ์ „ํžˆ ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค. @hramos ๋ฅผ ๋‹ค์‹œ ์—ฌ์‹ญ์‹œ์˜ค.

๊ทธ๋Ÿฐ ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์— ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ React Native์—์„œ ๊ณง์žฅ Native ์ฝ”๋“œ๋กœ ๋‹ค์‹œ ์ด๋™ํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜๋‹ค๋ฉด ์†์„ ๋‚ด๋ฐ€์–ด ๊ณ ์ณ์ฃผ์„ธ์š” @petersuwara

์ด ๋ฌธ์ œ๋Š” ์ž ์‹œ ๋‹ซํ˜€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ท€ํ•˜์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ _์ƒˆ ํ˜ธ๋ฅผ ์—ด๊ณ  ๊ฐ€๋Šฅํ•œ ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค. ์—ฌ๊ธฐ์— ๋ณด๊ณ ๋œ ์›๋ž˜ ๋ฌธ์ œ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฌธ์ œ๋ฅผ ์ž ๊ทธ๊ณ  ์žˆ์œผ๋ฉฐ, ์ดํ›„์— ๋Œ“๊ธ€์„ ๋‚จ๊ธด ๊ฐ ์‚ฌ๋žŒ์ด ๋˜‘๊ฐ™์€ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” Facebook์—์„œ FlatList _๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ_ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ถˆ๋งŒ์ด ์ œ๊ธฐ๋œ ์ ์€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํŠน์ • ํƒ์ƒ‰ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด์™€ ํ•จ๊ป˜ ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ฌ๋Š” ๊ฒƒ์€ ์žฌํ˜„ ๋‹จ๊ณ„์˜ ๋ช…ํ™•ํ•œ ๋ชฉ๋ก์ด๋‚˜ ์ด์ƒ์ ์œผ๋กœ๋Š” ์†Œ๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๊ฐ€ ํฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰