2017-03-26 5 views
2

私が反応シーンに新しいですが、私は、その構造とかなりよく知って、それを使用して簡単なWebアプリケーションを作ることは非常に少なくとも、どのようにこれは私が時間Reactは動作しないでください。Reactは、Reactの動作と同様に、変更されたコンポーネントのみをレンダリングしますか?

のための私の頭を悩ま得た私が使用してチックタックトーを作っていますリアクションネイティブ、私は現在Androidでのみ実験しています。これらは私が私の状況は

import Tile from "./Tile" 

export default class Playground extends React.Component { 
    constructor(props) { 
     super(props) 
     this.state = { 
      board: [["?", "?", "?"], ["?", "?", "?"], ["?", "?", "?"]], 
      turn: "X" 
     } 
    } 

    move(x, y) { 
     if (this.state.board[x][y] == "?") { 
      var currentTurn = this.state.turn 
      var currentBoard = this.state.board 
      currentBoard[x][y] = this.state.turn 
      this.setState({board: currentBoard}); 
      //this.isGameOver(x, y); 
     } 
    } 

    isGameOver(x, y) { 
     //Game Over Test 
    } 

    render() { 
     return (
      <View style={styles.container}> 
       <View style={styles.row}> 
        <Tile onPress={this.move.bind(this, 0, 0)} icon={this.state.board[0][0]}/> 
        <Tile onPress={this.move.bind(this, 0, 1)} icon={this.state.board[0][1]}/> 
        <Tile onPress={this.move.bind(this, 0, 2)} icon={this.state.board[0][2]}/> 
       </View> 
       <View style={styles.row}> 
        <Tile onPress={this.move.bind(this, 1, 0)} icon={this.state.board[1][0]}/> 
        <Tile onPress={this.move.bind(this, 1, 1)} icon={this.state.board[1][1]}/> 
        <Tile onPress={this.move.bind(this, 1, 2)} icon={this.state.board[1][2]}/> 
       </View> 
       <View style={styles.row}> 
        <Tile onPress={this.move.bind(this, 2, 0)} icon={this.state.board[2][0]}/> 
        <Tile onPress={this.move.bind(this, 2, 1)} icon={this.state.board[2][1]}/> 
        <Tile onPress={this.move.bind(this, 2, 2)} icon={this.state.board[2][2]}/> 
       </View> 
      </View> 
     ) 
    } 
} 

説明そしてもちろんタイル

export default class Tile extends React.Component { 
    constructor(props) { 
     super(props) 
    } 

    rand() { 
     return Math.random() * 256; 
    } 

    randColor() { 
     return "rgb(" + this.rand() + " ," + this.rand() + " ," + this.rand() + ")"; 
    } 

    determineIcon() { 
     if (this.props.icon == "X") { 
      return (<Text>O</Text>) 
     } else if (this.props.icon == "O") { 
      return (<Text>X</Text>) 
     } else { 
      return null; 
     } 
    } 

    render() { 
     console.log("Things are happening!") 
     return (
      <TouchableHighlight onPress={this.props.onPress} underlayColor={this.randColor()}> 
       <View style={[styles.square, {backgroundColor: this.randColor()}]}> 
        {this.determineIcon()} 
       </View> 
      </TouchableHighlight> 
     ) 
    } 
} 

のコードがそれでは私が最初に気づいたことは、私はタイルをクリックするたびだったと思う私のコードからの部品ですそれは正常にXに変更されたすべての色が再生成された私は私のアプリがすべてを再レンダリングしていることに気づいた。

私はそれがそのランダム関数の欠陥だと思って、すべての四角形をオレンジ色にすることにしましたが、私はそれがまだすべてを再描画しているのか、レンダリングが何回起こっているのかを見て、それが9回起こったのは間違いです。

最後の8つのタイルからonPressとアイコンのプロパティを削除し、それらを完全に静的なオブジェクトに変え、ボードを単純なブール値に変更して最初のタイルに渡しました。しかし、それはまだ9つの要素すべてをレンダリングしました。

誰かが私に説明してください。Reactは動作しないでください。

答えて

4

最近、新しい状態が設定されているとき(または小道具が変更されたとき)、この親コンポーネントの階層内のすべてのコンポーネントがrender機能を起動することがわかりました。これはReactで、React-Nativeには該当しません。これはReactのshouldComponentUpdate()がデフォルトでtrueになるためです。

これは、コンポーネントが実際に再度レンダリングされることを意味するものではありません。 Reactは、UIを更新する必要があるかどうかを把握するのに十分スマートで、 "Reconciliation"というプロセスの一部としては機能しません。

つまり、深い階層のコンポーネントがたくさんある場合、この動作はJSスレッドに多少のストレスを与える可能性があります。あなたはパフォーマンスの問題に実行する場合は、独自のロジックを実行する、またはちょうどそれがdocsに言うように代わりReact.ComponentReact.PureComponentから継承するshouldComponentUpdateを上書きすることができます。

あなたが特定のコンポーネントを決定した場合、あなたがかもしれない、プロファイリングの後に遅いです shouldComponentUpdate()を実装するReact.PureComponentから浅い小道具と状態比較を継承するように変更します。 あなたが手で書きたいと自信がある場合は、 this.propsとnextPropsを比較し、this.stateをnextStateと比較して falseを返すと、更新をスキップすることができます。

+1

バインドされたクリックハンドラが各レンダリングでの新しい参照であるため、PureComponentはここでは機能しません。詳細:https://medium.com/@f.bagnardi/react-purecomponent-considered-harmful-8155b5c1d4bc#.4l6psfoqi – FakeRainBrigand

+0

ありがとうございました!私のコンポーネントがReact-nativeで再レンダリングされているかどうかを調べる方法はありますか?(私はChromeのInspect> Render> Paint Flashingを使用してそれを行う方法を知っています。それは私が正しい方法でやっているかどうかをチェックする方法でした) – Mathspy

+0

@ Mathspyは一般的に言えば、あなたがパフォーマンスヒットにぶつからない限りレンダリングします。純粋なコンポーネントを使用して最適化することができます。 Reactは、コンポーネントが変更され、実際に再度レンダリングする必要があると判断すると、ブリッジからネイティブ側に渡され、適切なビューがリフレッシュされます。 – Artal

関連する問題