2016-04-25 69 views
0

我的目標是切換一個開關組件和值的變化,以影響將用不同於默認渲染樣式的樣式渲染的父代的狀態。反應本機列表視圖不改變狀態改變的風格

此刻狀態更新正常,但組件未重新呈現。

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

var SONGS_DATA = { 
    "songs" : [ 
    { 
     "title" : "I Heard React Was Good", 
     "artist" : "Martin", 
     "played" : false 
    }, 
    { 
     "title" : "Stack Overflow", 
     "artist" : "Martin", 
     "played" : false 
    } 
    ] 
} 

class BasicSwitchExample extends Component{ 
    constructor(props){ 
     super(props); 
     this.state = { 
     played: false 
     }; 
     this.handlePlayed = this.handlePlayed.bind(this); 
    } 
    handlePlayed(value){ 
     console.log('handlePlayed value: ' + value); 
     this.setState({played: value}); 
     this.props.callbackParent(value); 
    } 
    render() { 
     return <View> // this has to be on the same line or it causes an error for some reason 
     <Switch 
      onValueChange={this.handlePlayed} 
      style={{marginBottom: 10}} 
      value={this.state.played} /> 
     </View> 
    } 
} 

class AwesomeProject extends Component { 
    constructor(props) { 
    super(props); 
    this.renderSong = this.renderSong.bind(this); 
    this.togglePlayed = this.togglePlayed.bind(this); 
    this.fetchData = this.fetchData.bind(this); 
    this.state = { 
     dataSource: new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
     }), 
     loaded: false 
    }; 
    } 

    componentDidMount() { 
    this.fetchData(); 
    } 

    togglePlayed(value) { 
    // this is never reached 
    this.setState({played: value}); 
    console.log('Song has been played? ' + this.state.played); 
    } 

    fetchData() { 
    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(SONGS_DATA.songs), 
     loaded: true, 
    }); 
    } 

    render() { 
    if (!this.state.loaded) { 
     return this.renderLoadingView(); 
    } 

    return (
     <ListView 
     dataSource={this.state.dataSource} 
     renderRow={this.renderSong} 
     style={styles.listView} 
     /> 
    ); 
    } 

    renderLoadingView() { 
    return (
     <View style={styles.container}> 
     <Text> 
      Loading songs... 
     </Text> 
     </View> 
    ); 
    } 

renderSong(song) { 
    let bgStyle = this.state.played ? styles.played : styles.container; 
    console.log('style : ' + bgStyle); // prints 2 for some reason 
    return (
     <View style={this.state.played ? styles.played : styles.container}> 
     <View style={styles.half}> 
      <Text style={styles.title}>{song.title}</Text> 
      <Text style={styles.artist}>{song.artist}</Text> 
     </View> 
     <View style={styles.half}> 
     <BasicSwitchExample callbackParent={this.togglePlayed} /> 
     </View> 
     </View> 
    ); 
    } 
} 

var styles = StyleSheet.create({ 
    container: { 
    /* styles here */ 
    }, 
    played: { 
    /* styles here */ 
    }, 

}); 

AppRegistry.registerComponent('SampleApp',() => AwesomeProject); 

React Native Playground

出於某種原因,渲染風格時,它打印出來2。這隻會在應用程序第一次加載時發生,並且在切換開關後永遠不會到達。

回答

2

您不會改變任何與ListView呈現相關的狀態。在togglePlayed你必須改變將改變渲染列表的狀態的部分:https://rnplay.org/apps/z0fKKA

+0

謝謝馬克,我會看看那個遊樂場,唯一的事情是,控制檯輸出'宋已被播放?一旦添加新歌曲,就不確定。我希望你的答案能夠修正不切換開關的樣式,但不知道它是否只是未定義值的症狀。 – martincarlin87

+0

對不起,我錯過了你的需求:-)請再看看。我將組件「BasicSwitchExample」簡化爲無狀態函數,因爲它不需要狀態。然後我從狀態中刪除了dataSource,以便更容易地改變歌曲列表(播放:true/false)。目前的關鍵是標題,也許你想改變那個 –

+0

啊,那是完美的,非常感謝你,我現在要去學習它:) – martincarlin87