3

ここに私のサンプルコードがあります。ListView要素をクリックして更新します。アクティブViewは緑色で強調されるべきである。この例ではReactネイティブListViewは状態の変化をクリックして再レンダリングしません

(this.state.selectedField.id==field.id)?'green':'white' 

この行は、スタイルを定義します。状態はhandleClick()の内部で更新されていますが、renderField()メソッドが呼び出されていません。

どのようにリストビューをクリックすることによってトリガされた状態変化に再レンダリングするか?

RNPlayNative Link

import React, {Component} from 'react'; 
import { 
    AppRegistry, 
    View, 
    ListView, 
    Text, 
    TouchableOpacity 
} from 'react-native'; 

class SampleApp extends Component { 

    constructor(props) { 
    super(props); 
    var ds = new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
    }); 
    this.state = { 
     fields: ds.cloneWithRows([ 
     {id:0},{id:1},{id:2} 
     ]), 
     selectedField: {id:0} 
    }; 
    } 

    handleClick(field) { 
    console.log("Selected field:",field); 
    this.setState({ 
     selectedField: field 
    }); 
    } 

    renderField(field) { 
    return (
     <TouchableOpacity onPress={this.handleClick.bind(this, field)} > 
     <View style={{backgroundColor:(this.state.selectedField.id==field.id)?'green':'white'}}> 
      <Text style={{left:0, right:0, paddingVertical:50,borderWidth:1}}>{field.id}</Text> 
     </View> 
     </TouchableOpacity> 
    ); 
    } 

    render() { 
    return (
     <View> 
     <ListView 
      dataSource={this.state.fields} 
      renderRow={this.renderField.bind(this)} 
     /> 
     </View> 
    ); 
    } 
} 

AppRegistry.registerComponent('SampleApp',() => SampleApp); 
+0

はこれを試してみてくださいされています。私はすでにインラインスタイルを使用していますhttp://stackoverflow.com/questions/26882177/react-js-inline-style-best-practices –

+0

、問題は、スタイルをリンクしてクリックなどのイベントを動的にリンクすることです。 –

答えて

2

dataSourceが変更されたときにリストが再度レンダリングされます。この例では、dataSourceは決して変更されないので、listviewは決して再レンダリングされません。これは、dataSourceのデータを保持するための状態変数にフィールドを追加することで実現できます。また、componentDidMountメソッドでは、dataSourceにデータ状態変数を持つ行を複製させます。リストビューを再レンダリングしたいときはいつでも、データ状態変数のみを変更し、リストは自動的に再レン​​ダリングされます。すべてのオブジェクトで選択状態を追加するためにデータを変更しました。ここに更新されたコードがあります。ここで

class SampleApp extends Component { 

    constructor(props) { 
    super(props); 
    var ds = new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
    }); 
    var dataVar = [ 
     { 
      id:0, 
      selected: true, 
     },{ 
      id:1, 
      selected: false, 
     },{ 
      id:2, 
      selected: false, 
     } 
     ]; 
    this.state = { 
     data: dataVar, 
     fields: ds, 
    }; 
    } 

    componentDidMount() { 

    this.setState({ 
     fields: this.state.fields.cloneWithRows(dataVar) 
    }); 
    } 


    handleClick(field) { 
    console.log(field); 
    field.selected = !field.selected; 

    var dataClone = this.state.data; 
    console.log(dataClone); 

    dataClone[field.id] = field; 

    this.setState({ 
     data: dataClone, 
    }); 
    } 

    renderField(field) { 
    let color = (field.selected == true)?'green':'white'; 
    return (
     <TouchableOpacity onPress={this.handleClick.bind(this, field)} > 
     <View style={{backgroundColor:color}}> 
      <Text style={{left:0, right:0, paddingVertical:50,borderWidth:1}}>  {field.id}</Text> 
     </View> 
     </TouchableOpacity> 
    ); 
    } 

    render() { 
    return (
     <View> 
     <ListView 
      dataSource={this.state.fields} 
      renderRow={(field) => this.renderField(field)} 
     /> 
     </View> 
    ); 
    } 
} 

作業rnplay sample

+0

あなたは 'componentDidMount'の中でこの行を修正するのを忘れました:' fields:this.state.fields.cloneWithRows(this.state.data) ' –

+0

私は解決策を試しましたが、何らかの理由で' renderField() 'data'の更新時に機能します。 'handleClick()'が正常に動作し、 'data'が更新されます。 –

+0

さて、私はこれまでのところ動いています。私のアプリケーションには次の行があります: 'if(!this.state.loaded){ return this.renderLoadingView(); } '何らかの理由でデータがロードされるまでビューレンダリングを延期すると' renderField() 'コールがブロックされました。 –

0

は、質問に対する私の解決策になるが、それはまだすべてのクリックを処理するために時間がかかりすぎます。

handleClick(field) { 
    newFields = this.state.fields.map((x) => x.key === field.key && x.active !== true ? {...x,active:true} : {...x,active:false}) 
    this.setState({ 
    fields:newFields, 
    dataSource: this.state.dataSource.cloneWithRows(newFields) 
    }); 
} 
関連する問題