2016-08-16 2 views
0

componentWillReceiveProps가 실행될 때 listview를 새로 고치려고합니다. 가져온 후에 dataSource가 업데이트 된 것 같습니다 (render()에 console.log (this.state.dataSource)를 추가하고 끝점의 현재 상태에 따라 변경됨)dataSource가 업데이트되었지만 componentWillReceiveProps 이후 Listview가 react-native로 새로 고쳐지지 않습니다.

그러나 ListView는 동일하게 유지됩니다. 왜 그런지 궁금해서 dataSource에 대해 의심 스러웠습니다. 그래서 render()에서 dataSource를 출력 할 문자열 객체를 만들었습니다.

componentWillReceiveProps()가 실행될 상기 일부 변경 var str = JSON.stringify(this.state.dataSource._dataBlob.s1);

그리고 <View><Text>{str}</Text>. 그러나 listview는 동일하게 유지됩니다. 나는 이것이 일어나는 이유를 전혀 모르고있다.

다음은 내 코드 스 니펫입니다.

componentWillReceiveProps(){ 
    var query = ApiUrl.urlForWeekInfo(this.state.email); 
    console.log(query); 
    this._executeQuery(query,3); 
    } 


    constructor(props) { 
    super(props); 

    var dataSource = new ListView.DataSource(
     {rowHasChanged: (r1, r2) => r1.guid !== r2.guid}); 

     this.state = { 
     isLoading: false, 
     ... 
     first_name: this.props.first_name, 
     email: this.props.email, 
     dataSource: dataSource.cloneWithRows(this.props.listings)  
    }; 
    } 
.. 

_executeQuery(query,i) { 

    this.setState({ isLoading: true }); 
    fetch(query) 
     .then(response => response.json()) 
     .then(json => this._handleResponse(json.response,i)) 
     .catch(error => 
     this.setState({ 
      isLoading: false, 
      message: 'Something bad happened ' + error 
    })); 
    } 

    _handleResponse(response,i) { 
    this.setState({ isLoading: false , message: '' }); 
    if (response.application_response_code.substr(0, 1) === '1') { 
     if(i==1){ 
     this.props.navigator.push({ 
      title: 'Apply', 
      component: Apply, 
      passProps: {listings: response.listings, times: response.timetable, week_num: this.state.week_num} 
     }); 
     } else if (i==3){ 

     var output = response.listings; 
     this.setState({ 
      dataSource: this.state.dataSource.cloneWithRows(output) 
     }); 

     console.log(response.listings); 
     this.forceUpdate(); 

     } 
    } else { 
    } 
    } 

render() { 

    console.log(this.state.dataSource._dataBlob.s1); 

    var str = JSON.stringify(this.state.dataSource._dataBlob.s1); 
    var listviewsource = this.state.dataSource; 

    return (

    <View style={[this.border('red'), styles.container_top]}> 
     <View style={[this.border('black'), styles.container_top_buttons]} > 

     <ListView 
      dataSource={listviewsource} 
      renderRow={this.renderRow.bind(this)}/> 

     </View>  
     {spinner} 
     <View> 
     <Text>{str}</Text> 
     </View> 

    </View> 




     ); 
     }} 

아이디어 나 경험을 공유하십시오.


나는이 문제에 대한 해결책을 찾기 결국 :

var array = response.listings; 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    //=> call another ds variable. 

    this.setState({ 
     rawData: array, 
     dataSource: ds.cloneWithRows(response.listings) 
    }); 

답변

1

당신의 ListView에 행을 업데이트 할 직접적인 방법이 없습니다. 밖에 ListView.DataSource에 관한 많은 문서가 없습니다. 당신은 ListView에 행을 추가// 앞에 추가/업데이트를 추가/삭제하려면 그래서 여기, 당신은 setState를()에서 바로 데이터 소스를 업데이트하고 cloneWithRows를 호출하기 만하면됩니다

을 goes-.

예를 들어. URL에서 데이터를 가져 오려고합니다. "Load more"를 누를 때마다 데이터 소스에 새 행을 추가합니다. 난생 처음에서

getInitialState: function(){ 
    return { 
     rawData: [], 
     dataSource: new ListView.DataSource({ 
      rowHasChanged: (row1, row2) => row1 !== row2 
     }), 
     loaded: false, 
     page: 1, 
    } 
}, 

, 나는 상태에서 초기 데이터를 내 ListView를 채 웁니다 ComponentDidMount 함수()와 "페이지"= 1을 호출합니다.

reloadData: function(){ 
    this.setState({ loaded: false, rawData: [], page: 1 }); 

    API.getUpcomingMovies(this.state.page) 
     .then((data) => { 
      this.setState({ 
      rawData: this.state.rawData.concat(data), 
      dataSource: this.state.dataSource.cloneWithRows(this.state.rawData.concat(data)), 
      loaded: true, 
      }); 
     }); 
    }, 

그리고 API에서 JSON을 가져 오기 위해 "추가로드"를 탭 할 때마다 다음 함수를 호출합니다. 여기서 "페이지로드"가 증가 할 때마다 "페이지"가 ​​증가합니다.

여기서 알 수 있듯이, rawData [] (JSON 개체를 포함하는 간단한 배열)를 연결합니다. 원시 데이터에 새로운 데이터를 추가하려면 다음과 같이 할 수 있습니다.

this.setState({ 
    rawData: data.concat(this.state.rawData) 
)} 
+0

제 경우에는 모든 것을 연결하거나 앞에 추가하지 않고 전체를 다시로드 할 필요가 없습니다. cloneWithRows 문으로 dataSource를 만졌을지라도 그것은 나에게 적합하지 않았습니다. 나는 '새로운 ListView'를 사용하려고 시도했다. 그런 방식으로 어떤 부정적인면을 제안 해 주시겠습니까? –

+0

@SungpahLee 정말 아무것도! 당신이 한 일은 본질적으로 나의 발췌 문장과 같습니다. 나는'getInitialState()'에'새로운 ListView'를 가지고 있고 당신은'constructor()'에 같은 것을 가지고 있습니다. 그래서 IMO 나는이 접근법에 어떤 단점도 보지 못했다. 그러나 다른 견해를 환영합니다. 또한 연결 대신 데이터를 직접 바꿀 수 있습니다. 요지는 이러한 원시적 인 작업보다 중요합니다. 데이터를 다시 렌더링하려면'cloneWithRows (newdata)'를 호출하여 state.dataSource를 업데이트하기 만하면됩니다. – Mihir

관련 문제