ãªã¹ãã¯ã¢ãã€ã«ã¢ããªéçºã®éèŠãªéšåã§ã
ãªã¹ãã¯ãã¢ãã€ã«ã¢ããªã®æ žå¿ã§ãã å€ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ããªã¹ãã衚瀺ããŸããããã¯ãFacebookã¢ããªã±ãŒã·ã§ã³ãã£ãŒãã®åºçç©ã®ãªã¹ããã¡ãã»ã³ãžã£ãŒã®ãã£ãããªã¹ããGmailã¡ãŒã«ã®ãªã¹ããInstagramã®åçã®ãªã¹ããTwitterã®ãã€ãŒãã®ãªã¹ããªã©ã§ãã
èšå€§ãªæ°ã®ããŒã¿ãœãŒã¹ãæ°åè¡ã倧éã®ã¡ã¢ãªãå¿ èŠãšããã¡ãã£ã¢ãã¡ã€ã«ãªã©ããªã¹ããããè€éã«ãªããšããã®éçºãé£ãããªããŸãã
äžæ¹ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®é床ãç¶æããå¿ èŠããããŸãããªããªãã 60 FPSã¹ã¯ããŒã«ã¯ããã€ãã£ããšã³ã²ãŒãžã¡ã³ããšã¯ã¹ããªãšã³ã¹ïŒUXïŒã®ãŽãŒã«ãã¹ã¿ã³ããŒãã«ãªããŸããã äžæ¹ãã¢ãã€ã«ããã€ã¹ã«ã¯éå°ãªãªãœãŒã¹ããªããããã¡ã¢ãªã®æ¶è²»ãäœãæããå¿ èŠããããŸãã ãããã®äž¡æ¹ã®æ¡ä»¶ãæºããããšã¯å¿ ããã容æã§ã¯ãããŸããã
ListViewã®å®ç§ãªå®è£ ãèŠã€ãã
ãœãããŠã§ã¢éçºã®åºæ¬çãªã«ãŒã«ã¯ãã©ã®ã·ããªãªã§ãæé©åãäºæž¬ã§ããªãããšã§ãã å¥ã®åéã®äŸãèŠãŠã¿ãŸããããããŒã¿ãä¿åããã®ã«çæ³çãªããŒã¿ããŒã¹ã¯ãããŸããã äžéšã®ãŠãŒã¹ã±ãŒã¹ã«æé©ãªSQLããŒã¿ããŒã¹ãããã³ä»ã®ç¶æ³ã«æé©ãªNoSQLããŒã¿ããŒã¹ã«ç²ŸéããŠããå ŽåããããŸãã ç¬èªã®ããŒã¿ããŒã¹ãéçºããå¯èœæ§ã¯äœãããããœãããŠã§ã¢éçºè ãšããŠãç¹å®ã®åé¡ã解決ããããã®é©åãªããŒã«ãéžæããå¿ èŠããããŸãã
ãªã¹ãã®è¡šç€ºã«ãåãã«ãŒã«ãé©çšãããŸãããªã¹ãã®è¡šç€ºãå®è£ ããæ¹æ³ã¯ãã©ã®ãŠãŒã¹ã±ãŒã¹ã«ãé©ããŠããã ãã§ãªããåæã«é«ãFPSé床ãšäœã¡ã¢ãªèŠä»¶ãç¶æããæ¹æ³ãèŠã€ããå¯èœæ§ã¯äœãã§ãã
倧ãŸãã«èšãã°ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã§ãªã¹ãã䜿çšããããã®ãªãã·ã§ã³ã«ã¯2ã€ã®ã¿ã€ãããããŸãã
â¢éåžžã«å€§ããªããŒã¿ãœãŒã¹ãæã€ã»ãŒåäžã®è¡ã é£çµ¡å ãªã¹ãã®è¡ã¯åãããã«èŠããæ§é ãåãã§ãã ãŠãŒã¶ãŒãæ¢ããŠãããã®ãèŠã€ãããŸã§ãæååããã°ããé²èŠ§ã§ããããã«ããŠãã ããã äŸïŒã¢ãã¬ã¹åž³ã
â¢éåžžã«ç°ãªãè¡ãšå°ããªããŒã¿ãœãŒã¹ã ããã§ã¯ããã¹ãŠã®è¡ãç°ãªããç°ãªãéã®ããã¹ããå«ãŸããŠããŸãã äžéšã«ã¯ã¡ãã£ã¢ãå«ãŸããŠããŸãã ã»ãšãã©ã®å ŽåããŠãŒã¶ãŒã¯ã¹ããªãŒã å šäœã衚瀺ããã®ã§ã¯ãªããã¡ãã»ãŒãžãé çªã«èªã¿åããŸãã äŸïŒãã£ããã¡ãã»ãŒãžã
ç°ãªããŠãŒã¹ã±ãŒã¹ã«åå²ããããšã®å©ç¹ã¯ããªãã·ã§ã³ããšã«ç°ãªãæé©åææ³ãæäŸã§ããããšã§ãã
æ¢è£œã®React Nativeãªã¹ã
React Nativeã«ã¯ãããã«äœ¿ããListViewå®è£ ãä»å±ããŠããŸãã ã¹ã¯ããŒã«æã«ç»é¢ã«è¡šç€ºãããè¡ã®ãé 延èªã¿èŸŒã¿ããåæç»ã®åæ°ãæå°éã«æãããããŸããŸãªã€ãã³ãã«ãŒãã§ç·ãæç»ãããªã©ãéåžžã«åççãªæé©åãå«ãŸããŠããŸãã
ListViewã®å®æããå®è£ ã®ãã1ã€ã®èå³æ·±ãç¹æ§ã¯ãReact Nativeã®äžéšã§ãããã€ãã£ãScrollViewã³ã³ããŒãã³ããä»ããŠJavaScriptã§å®å šã«å®è£ ãããŠããããšã§ãã iOSãŸãã¯Androidã®éçºçµéšãããå Žåããã®äºå®ã¯å¥åŠã«æãããããããŸããã ãã€ãã£ãéçºãããïŒSDKïŒã¯ãiOSçšã®UITableViewãšAndroidçšã®ListViewã®ãªã¹ããã¥ãŒã®å®çžŸã®ããå®è£ ã«åºã¥ããŠããŸãã React NativeããŒã ã䜿çšããªããšæ±ºãããã®ã¯ãªãããšã¯æ³šç®ã«å€ããŸãã
ããã«ã¯ããŸããŸãªçç±ããããããããŸããããããã¯ä»¥åã«å®çŸ©ããããŠãŒã¹ã±ãŒã¹ã«ãããã®ãšæãããŸãã iOSã®UITableViewãšAndroidã®ListViewã¯ãæåã®ãŠãŒã¹ã±ãŒã¹ã«ã»ãŒå®å šã«æ©èœããé¡äŒŒã®æé©åææ³ã䜿çšããŸã-ã»ãšãã©åäžã®è¡ãšéåžžã«å€§ããªããŒã¿ãœãŒã¹ã®ãªã¹ãã å®æããListView React Nativeã¯ã2çªç®ã®ãªãã·ã§ã³çšã«æé©åãããŠããŸãã
Facebookãšã³ã·ã¹ãã ã®äž»ãªãªã¹ãã¯ãFacebookæçš¿ãã£ãŒãã§ãã Facebookã¢ããªã±ãŒã·ã§ã³ã¯ãReact Nativeãç»å Žããããªãåã«iOSãšAndroidã«å®è£ ãããŸããã ããããããŒãã®å ã®å®è£ ã¯ãiOSã®UITableViewãšAndroidã®ListViewã®ãã€ãã£ãå®è£ ã«å®éã«åºã¥ããŠãããããæ³åã§ããããã«ãæåŸ ã©ããã«æ©èœããŸããã§ããã ããŒãã¯ã2çªç®ã®ãŠãŒã¹ã±ãŒã¹ã®å žåçãªäŸã§ãã è¡ã¯éåžžã«ç°ãªã£ãŠããŸãããªããªã ãã¹ãŠã®åºçç©ã¯ç°ãªããŸã-ãããã¯ã³ã³ãã³ãã®éãç°ãªããç°ãªãçš®é¡ã®ã¡ãã£ã¢ãã¡ã€ã«ãå«ã¿ãç°ãªãæ§é ãæã£ãŠããŸãã ãŠãŒã¶ãŒã¯ãã£ãŒãå ã®åºçç©ãé çªã«èªã¿ãéåžžã¯äžåºŠã«äœçŸè¡ãã¹ã¯ããŒã«ããŸããã
ã§ã¯ããªãåå©çšãæ€èšããªãã®ã§ããïŒ
2çªç®ã®ãŠãŒã¹ã±ãŒã¹ïŒéåžžã«ç°ãªãè¡ãšå°ããªããŒã¿ãœãŒã¹ãæã€ãªã¹ãïŒãã±ãŒã¹ã«é©ããŠããå Žåã¯ãæ¢è£œã®ListViewå®è£ ãéžæããããšãæ€èšããå¿ èŠããããŸãã æåã®ãŠãŒã¹ã±ãŒã¹ã§ã±ãŒã¹ã説æãããŠããŠãå®æããå®è£ ã®äœæ¥ã«æºè¶³ã§ããªãå Žåã¯ã代æ¿ãªãã·ã§ã³ãè©ŠããŠã¿ãããšããå§ãããŸãã
æåã®ãŠãŒã¹ã±ãŒã¹ã¯ãã»ãšãã©åäžã®è¡ãšéåžžã«å€§ããªããŒã¿ãœãŒã¹ãæã€ãªã¹ãã§ããããšãæãåºããŠãã ããã ãã®ã·ããªãªã§ã¯ãæå¹ã§ããããšã蚌æãããŠããäž»ãªæé©åææ³ã¯æååã®åå©çšã§ãã
ããŒã¿ãœãŒã¹ã¯éåžžã«å€§ããå¯èœæ§ãããããããã¹ãŠã®è¡ãåæã«ã¡ã¢ãªã«æ ŒçŽã§ããªãããšã¯æããã§ãã ã¡ã¢ãªæ¶è²»ãæå°éã«æããããã«ãçŸåšç»é¢ã«è¡šç€ºãããŠããè¡ã®ã¿ãä¿åããŸãã ã¹ã¯ããŒã«ã®çµæãšããŠè¡šç€ºãããªããªã£ãè¡ã¯è§£æŸããã衚瀺ãããæ°ããè¡ã¯ã¡ã¢ãªã«é 眮ãããŸãã
ãã ããã¹ã¯ããŒã«äžã«åžžã«ã¡ã¢ãªå ã®è¡ã解æŸããŠé 眮ããã«ã¯ãéåžžã«éäžçãªããã»ããµäœæ¥ãå¿ èŠã§ãã ãã®ãã€ãã£ãã¢ãããŒãã䜿çšãããšã60 FPSã®æãŸããé床ãéæã§ããªãå ŽåããããŸãã 幞ããªããšã«ããã®äœ¿çšäŸã§ã¯ãæååã¯ã»ãšãã©åãã§ãã ã€ãŸããç»é¢ããã¹ã¯ããŒã«ãããè¡ã解æŸãã代ããã«ã衚瀺ãããŠããããŒã¿ãæ°ããè¡ã®ããŒã¿ã§çœ®ãæããã ãã§æ°ããè¡ãäœæããæ°ããã¡ã¢ãªäœçœ®ãåé¿ã§ããŸãã
å®çšçãªéšåã«ç§»ããŸãããã ãã®ãŠãŒã¹ã±ãŒã¹ãè©Šãããã«äŸãçšæããŸãã ãã®äŸã«ã¯ãåãæ§é ã®3,000è¡ã®ããŒã¿ãå«ãŸããŸãã
import React, { Component } from 'react'; import { Text, View, Dimensions } from 'react-native'; import RecyclingListView from './RecyclingListView'; const ROWS_IN_DATA_SOURCE = 3000; const dataSource = []; for (let i=0; i<ROWS_IN_DATA_SOURCE; i++) dataSource.push(`This is the data for row # ${i+1}`); export default class RecyclingExample extends Component { render() { return ( <View style={{flex: 1, paddingTop: 20,}}> <RecyclingListView renderRow={this.renderRow} numRows={dataSource.length} rowHeight={50} /> </View> ); } renderRow(rowID) { return ( <Text style={{ width: Dimensions.get('window').width, height: 50, backgroundColor: '#ffffff' }}>{dataSource[rowID]}</Text> ); view rawRecyclingExample.js hosted with by GitHub } }
UITableViewã®ãã€ãã£ãå®è£ ã䜿çšãã
åè¿°ã®ããã«ãiOSããã³Androidã®ãã€ãã£ãSDKã«ã¯ãæååãæžãæããå ç¢ãªå®è£ ããããŸãã iOSã«çŠç¹ãåãããUITableViewã䜿çšããŸãã
ãã®ãã¯ããã¯ãJavaScriptã§å®å šã«å®è£ ããããšããªãçç±ãçåã«æããããããŸããã ããã¯èå³æ·±ã質åã§ãããããã€ãã®åå¥ã®ããã°ãšã³ããªã®è©³çŽ°ãªèª¬æã«å€ããŸãã ãã ããèŠããã«ãè¡ãé©åã«äžæžãããã«ã¯ãçŸåšã®ã¹ã¯ããŒã«ãªãã»ãããåžžã«ç¥ã£ãŠããå¿ èŠããããŸããã¹ã¯ããŒã«ãããšãã«è¡ãäžæžãããå¿ èŠãããããã§ãã ã¹ã¯ããŒã«ã€ãã³ãã¯ãã€ãã£ããŸãŒã³ã§çºçãã RNããªããžãééãããã©ã³ãžã·ã§ã³ã®æ°ãæžããããã«ãã€ãã³ãã远跡ããããšã¯çã«ããªã£ãŠããŸãã
Objective-C: #import "RNTableViewManager.h" #import "RNTableView.h" @implementation RNTableViewManager RCT_EXPORT_MODULE() - (UIView *)view { return [[RNTableView alloc] initWithBridge:self.bridge]; } RCT_EXPORT_VIEW_PROPERTY(rowHeight, float) RCT_EXPORT_VIEW_PROPERTY(numRows, NSInteger) @end
ã©ãããŒèªäœã¯RNTableView.mã§å®è¡ãããäž»ã«ããããã£ã®è»¢éãšé©åãªå Žæã§ã®ããããã£ã®äœ¿çšãåŠçããŸãã 次ã®å®è£ ã®è©³çŽ°ã«ç«ã¡å ¥ãå¿ èŠã¯ãããŸããããŸã èå³æ·±ãéšåãæ¬ ããŠããããã§ãã
#import "RNTableView.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" #import "RCTUtils.h" #import "UIView+React.h" @interface RNTableView()<UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) UITableView *tableView; @end @implementation RNTableView RCTBridge *_bridge; RCTEventDispatcher *_eventDispatcher; NSMutableArray *_unusedCells; - (instancetype)initWithBridge:(RCTBridge *)bridge { RCTAssertParam(bridge); if ((self = [super initWithFrame:CGRectZero])) { _eventDispatcher = bridge.eventDispatcher; _bridge = bridge; while ([_bridge respondsToSelector:NSSelectorFromString(@"parentBridge")] && [_bridge valueForKey:@"parentBridge"]) { _bridge = [_bridge valueForKey:@"parentBridge"]; } _unusedCells = [NSMutableArray array]; [self createTableView]; } return self; } RCT_NOT_IMPLEMENTED(-initWithFrame:(CGRect)frame) RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) - (void)layoutSubviews { [self.tableView setFrame:self.frame]; } - (void)createTableView { _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; _tableView.dataSource = self; _tableView.delegate = self; _tableView.backgroundColor = [UIColor whiteColor]; [self addSubview:_tableView]; } - (void)setRowHeight:(float)rowHeight { _tableView.estimatedRowHeight = rowHeight; _rowHeight = rowHeight; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView { return 1; } - (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section { return self.numRows; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return self.rowHeight; } // @end
éèŠãªæŠå¿µ-ãã€ãã£ãç°å¢ãšJSã®æ¥ç¶
è¡å šäœãããžãã¹ããžãã¯ã§ãããããJavaScriptã§å®çŸ©ãããReactã³ã³ããŒãã³ãã«ããå¿ èŠããããŸãã ããããããããç°¡åã«æ§æã§ããããã«ãããã®ã§ãã å®éã®æžãæãããžãã¯ã¯ãã€ãã£ãç°å¢ã§æ©èœããããããããã®ã³ã³ããŒãã³ããäœããã®æ¹æ³ã§JSããã転éãããå¿ èŠããããŸãã
Reactã³ã³ããŒãã³ãããã€ãã£ãã³ã³ããŒãã³ãã«åãšããŠæž¡ãããšããå§ãããŸãã JSã®ãã€ãã£ãã³ã³ããŒãã³ãã䜿çšããŠãåã³ã³ããŒãã³ããšããŠJSXã«æååãè¿œå ãããšãReact Nativeã¯ãããããã€ãã£ãã³ã³ããŒãã³ãã«è¡šç€ºãããUIViewãã¥ãŒã«åŒ·å¶çã«å€æããŸãã
ç§Theã¯ãããŒã¿ãœãŒã¹ã®ãã¹ãŠã®è¡ããã³ã³ããŒãã³ããäœæããå¿ èŠããªãããšã§ãã ç§ãã¡ã®äž»ãªç®æšã¯æååãåå©çšããããšãªã®ã§ãç»é¢ã«è¡šç€ºããã®ã«å¿ èŠãªã®ã¯ãããããã§ãã ç»é¢ã«20è¡ãåæã«è¡šç€ºããããšä»®å®ããŸãã ãã®å€ã¯ãç»é¢ã®é«ãïŒiPhone 6 Plusã®å Žåã¯736ã®è«çãã€ã³ãïŒãåè¡ã®é«ãïŒãã®å Žåã¯50ïŒã§é€ç®ããçŽ15ã®å€ãååŸããŠãããããã€ãã®è¡ãè¿œå ããããšã§ååŸã§ããŸãã
ãããã®20è¡ãåæåã®ããã«ãµããã¥ãŒã®åãšããŠã³ã³ããŒãã³ãã«æž¡ããããšãããããã¯ãŸã 衚瀺ãããŠããŸããã ç§ãã¡ã¯ãããããæªäœ¿çšã®ã»ã«ãã®ãã³ã¯ã«ä¿ç®¡ããŸãã
以äžãæãèå³æ·±ãã§ãã UITableViewã®ãã€ãã£ãæžãæãã¯ããdequeueReusableCellãã¡ãœããã䜿çšããŠæ©èœããŸãã ã»ã«ãïŒç»é¢ã«è¡šç€ºãããŠããªãè¡ããïŒäžæžãã§ããå Žåããã®æ¹æ³ã䜿çšããŠãæžãæããããã»ã«ãè¿ãããšãã§ããŸãã ã»ã«ãäžæžãã§ããªãå Žåãæ°ããã³ãŒããã¡ã¢ãªã«é 眮ããå¿ èŠããããŸãã æ°ããã»ã«ã®é 眮ã¯ãç®ã«èŠããç·ã§ç»é¢ãåããåã®æåã«ã®ã¿è¡ãããŸãã ã§ã¯ãæ°ããã»ã«ãã¡ã¢ãªã«é 眮ããæ¹æ³ã¯ïŒ éè¡ã®æªäœ¿çšã®ã»ã«ã®1ã€ãååŸããŸãã
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex { // subview, // [super insertSubview:subview atIndex:atIndex]; [_unusedCells addObject:subview]; } - (UIView*) getUnusedCell { UIView* res = [_unusedCells lastObject]; [_unusedCells removeLastObject]; if (res != nil) { res.tag = [_unusedCells count]; } return res; } - (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CustomCell"; TableViewCell *cell = (TableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; cell.cellView = [self getUnusedCell]; NSLog(@"Allocated childIndex %d for row %d", (int)cell.cellView.tag, (int)indexPath.row); } else { NSLog(@"Recycled childIndex %d for row %d", (int)cell.cellView.tag, (int)indexPath.row); } // ⊠return cell; }
ããºã«ã®æåŸã®èŠçŽ ã¯ãããŒã¿ãœãŒã¹ããã®ããŒã¿ã§æ°ããäžæžã/äœæãããã»ã«ãåããããšã§ãã ã·ãªãŒãºã¯Reactã³ã³ããŒãã³ãã§ããããããã®ããã»ã¹ãReactã®çšèªã«å€æããŸãã衚瀺ããããŒã¿ãœãŒã¹ã®æ£ããè¡ã«åºã¥ããŠãè¡ã®ã³ã³ããŒãã³ãã«æ°ããããããã£ãå²ãåœãŠãå¿ èŠããããŸãã
ããããã£ã®å€æŽã¯JSç°å¢ã§çºçãããããJavaScriptã§çŽæ¥ãããè¡ãå¿ èŠããããŸãã ããã¯ãããããã®ã·ãªãŒãºã®ãã€ã³ãã£ã³ã°ãè¿ãå¿ èŠãããããšãæå³ããŸãã ãããè¡ãã«ã¯ãã€ãã³ãããã€ãã£ãç°å¢ããJSã«æž¡ããŸãã
ããã¯ãé¢æ°ã®å®å šãªå®è£ ã§ãããäžè¶³ããŠããéšåããã¹ãŠå«ãŸããŠããŸãã
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"CustomCell"; TableViewCell *cell = (TableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; cell.cellView = [self getUnusedCell]; NSLog(@"Allocated childIndex %d for row %d", (int)cell.cellView.tag, (int)indexPath.row); } else { NSLog(@"Recycled childIndex %d for row %d", (int)cell.cellView.tag, (int)indexPath.row); } // JS NSDictionary *event = @{ @"target": cell.cellView.reactTag, @"childIndex": @(cell.cellView.tag), @"rowID": @(indexPath.row), @"sectionID": @(indexPath.section), }; [_eventDispatcher sendInputEventWithName:@"onChange" body:event]; return cell; }
ãã¹ãŠãŸãšããŠ
ããã«ãRecyclingListView.jsã®æçµçãªå®è£ ã«ã¯ãJavaScriptã®ãã€ãã£ãã³ã³ããŒãã³ãã®ãã€ã³ãã£ã³ã°ãå¿ èŠã§ãã
import React, { Component } from 'react'; import { requireNativeComponent, View } from 'react-native'; import ReboundRenderer from './ReboundRenderer'; const RNTableViewChildren = requireNativeComponent('RNTableViewChildren', null); const ROWS_FOR_RECYCLING = 20; export default class RecyclingListView extends Component { constructor(props) { super(props); const binding = []; for (let i=0; i<ROWS_FOR_RECYCLING; i++) binding.push(-1); this.state = { binding: binding // childIndex -> rowID }; } render() { const bodyComponents = []; for (let i=0; i<ROWS_FOR_RECYCLING; i++) { bodyComponents.push( <ReboundRenderer key={'r_' + i} boundTo={this.state.binding[i]} render={this.props.renderRow} /> ); } return ( <View style={{flex: 1}}> <RNTableView style={{flex: 1}} onChange={this.onBind.bind(this)} rowHeight={this.props.rowHeight} numRows={this.props.numRows} > {bodyComponents} </RNTableView> </View> ); } onBind(event) { const {target, childIndex, rowID, sectionID} = event.nativeEvent; this.state.binding[childIndex] = rowID; this.setState({ binding: this.state.binding }); } }
è¿œå ãããå¥ã®æé©åã¯ãåæç»ã®åæ°ãæå°éã«ããããšã§ãã ã€ãŸã è¡ãäžæžãããããã€ã³ãã£ã³ã°ãå€æŽãããå Žåã«ã®ã¿ãè¡ãåæç»ããå¿ èŠããããŸãã
ãã®ããã«ã¯ãReboundRendererãå¿ èŠã§ãã ãã®åçŽãªJSã³ã³ããŒãã³ãã®ãã©ã¡ãŒã¿ãŒãšããŠããã®ã³ã³ããŒãã³ããçŸåšãã€ã³ããããŠããããŒã¿ãœãŒã¹ã®è¡ã®ã€ã³ããã¯ã¹ãååŸãããŸãïŒãã©ã¡ãŒã¿ãŒ "boundTo"ïŒã ãã€ã³ãã£ã³ã°ãå€æŽãããšãã«ã®ã¿åæç»ããŸãïŒæšæºã®æé©åshouldComponentUpdateã䜿çšïŒïŒ
var React = require('React'); var ReboundRenderer = React.createClass({ propTypes: { boundTo: React.PropTypes.number.isRequired, render: React.PropTypes.func.isRequired, }, shouldComponentUpdate: function(nextProps): boolean { return nextProps.boundTo !== this.props.boundTo; }, render: function(): ReactElement<any> { console.log('ReboundRenderer render() boundTo=' + this.props.boundTo); return this.props.render(this.props.boundTo); }, }); module.exports = ReboundRenderer;
ããã«ã³ãŒããå«ã倧éšåã®å®å šã«æ©èœããäŸã¯ã ãã®ãªããžããªã«ãããŸã ã
ãªããžããªã«ã¯ãèå³ã®ããä»ã®ããã€ãã®å®éšã®èª¬æãå«ãŸããŠããŸãã tableview-children.ios.jså®éšããã®ã±ãŒã¹ã«é©çšãããŸãã
Tal Kolã¯ãiOSããã³Androidçšã®ãã€ãã£ãã¢ãã€ã«ã¢ããªã®éçºãå°éãšãããã«ã¹ã¿ãã¯ã®éçºè ã§ãã React Nativeã¯åœŒã®æ°ãã趣å³ã§ãã Talã¯2ã€ã®ãã¯ãããžãŒäŒæ¥ã®å ±åèšç«è ã§ããããã®ãã¡ã®1ã€ã¯çŸåšWix.com ãµã€ããäœæããããã®ãã©ãããã©ãŒã ã«å±ããŠããŸã ã
å ã®èšäºïŒ Wix Engineers Blog