Programing

고정되지 않고 고정된 개체에서 키를 설정하려고 시도한 경우

c10106 2022. 4. 8. 18:54
반응형

고정되지 않고 고정된 개체에서 키를 설정하려고 시도한 경우

다음 예시:

  • MapView의 요소를 표시하다ListView주석으로
  • 클릭ListView원소는 그것을 파란색으로 칠하게 해야 한다.
  • 보너스(인 경우MapView그리고ListView국가 사물을 효율적으로 사용하다.

수정하기DataSourceListView...일 때 갈등을 일으키는 것 같다.active특성 수정:

불변성을 의미하고 동결된 개체에 대해 'false' 값을 사용하여 키를 'active'로 설정하려고 시도한 경우.

여기에 이미지 설명을 입력하십시오.

국가를 설정하는 올바른 방법은 무엇인가?

RNPlay 예제

'use strict';

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

var annotations = [
        {
          title: 'A',active: false,latitude: 45,longitude: 26,latitudeDelta: 0.015,longitudeDelta: 0.015,
        },{
          title: 'B',active: false,latitude: 49,longitude: 14,latitudeDelta: 0.015,longitudeDelta: 0.015,
        },{
          title: 'C',active: false,latitude: 26,longitude: 25,latitudeDelta: 0.015,longitudeDelta: 0.015,
        }
      ]

class SampleApp extends Component {

  constructor(props) {
    super(props);
    var ds = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
    });
    this.state = {
      region: annotations[0],
      annotations: annotations,
      dataSource: ds.cloneWithRows(annotations)
    };
  }

  handleClick(field) {
    if (this.previousField) {
      this.previousField.active = false;
    }
    this.previousField = field;
    field.active = true;
    this.setState({
      region: field,
    });
  }

  renderField(field) {
    let color = (field.active == true)?'blue':'yellow'; 

    return (
      <TouchableOpacity onPress={this.handleClick.bind(this,field)}>
        <Text style={{backgroundColor:color,borderWidth:1}}>{field.title}</Text>
      </TouchableOpacity>
    );
  }

  render() {
    return (
      <View style={{flex:1,flexDirection:'column',alignSelf:'stretch'}}>
        <MapView
            style={{flex:0.5,alignSelf:'stretch',borderWidth:1}}
          region={this.state.region}
          annotations={this.state.annotations}
        />
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(field) => this.renderField(field)}
        />
      </View>
    );
  }
}

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

문제

설정할 때field.active = true;또는this.previousField.active = false;, 객체를 수정하는 중(field의 데이터 소스에 존재하는ListView. TheListView데이터 원본을 생성할 때 데이터 원본을 중지하기 때문에 오류를 발생cloneWithRows. 데이터 소스를 일반적인 Resact 구성 요소 수명 주기(예:setState). 대신,ListView.DataSource물체는 다음과 같이 변경되도록 설계된다.cloneWithRows기존 데이터 소스의 복사본을 반환하는 기능.

Redex 라이브러리에 익숙하다면, 기존 상태를 수정하기보다는 Reducer 기능을 통해 주의 사본을 반환하도록 하는 철학과 매우 유사하다.

데이터 원본 복제

이 문제를 해결하기 위해, 돌연변이 대신field당신의 안에 있는 사물들handleClick함수, 당신이 정말로 하고 싶은 것은 이미 설정된 값을 가진 새로운 데이터 배열을 만드는 것이다(예:active()를 누른 후 호출한다.setState새로운 데이터 소스와 함께ListView으로 창조된.cloneWithRows. 이렇게 하면 실제로도 그런 건 필요 없다.annotations네 상태를 입력해봐.

여기서 코드는 단어보다 더 도움이 될 수 있다.

handleClick(field) {

  //iterate over annotations, and update them.
  //I'm taking 'title' as a unique id property for each annotation, 
  //for the sake of the example.
  const newAnnotations = annotations.map(a => {
    //make a copy of the annotation.  Otherwise you'll be modifying
    //an object that's in your listView's datasource,
    //and therefore frozen.
    let copyA = {...a};
    if (copyA.title === field.title) {
      copyA.active = true;
    } else {
      copyA.active = false;
    }
    return copyA;
  });

  this.setState({
    region: {...field, active: true},
    dataSource: this.state.dataSource.cloneWithRows(newAnnotations),
  });
}

이게 도움이 되었으면 좋겠어!여기 네가 올린 코드 조각이 있어. 내 수정사항과 함께.네가 설명한 대로 나는 미국 원주민보다 0.29반응 Native를 사용하여 iOS에서작동해야 한다.당신이 안드로이드맵뷰라는 질문에 태그를 달았으니, 나는 당신이 안드로이드를 운영하고 있다고 추측하지만, 플랫폼이 이 경우에 실제로 차이를 만들어서는 안 된다.

'use strict';

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

var annotations = [
        {
          title: 'A',active: false,latitude: 45,longitude: 26,latitudeDelta: 0.015,longitudeDelta: 0.015,
        },{
          title: 'B',active: false,latitude: 49,longitude: 14,latitudeDelta: 0.015,longitudeDelta: 0.015,
        },{
          title: 'C',active: false,latitude: 26,longitude: 25,latitudeDelta: 0.015,longitudeDelta: 0.015,
        }
      ]

class SampleApp extends Component {

  constructor(props) {
    super(props);
    var ds = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
    });
    this.state = {
      region: annotations[0],
      dataSource: ds.cloneWithRows(annotations)
    };
  }

  handleClick(field) {

    //iterate over annotations, and update them.
    //I'm taking 'title' as a unique id property for each annotation, 
    //for the sake of the example.
    const newAnnotations = annotations.map(a => {
      //make a copy of the annotation.  Otherwise you'll be modifying
      //an object that's in your listView's datasource,
      //and therefore frozen.
      let copyA = {...a};
      if (copyA.title === field.title) {
        copyA.active = true;
      } else {
        copyA.active = false;
      }
      return copyA;
    });

    this.setState({
      region: {...field, active: true},
      dataSource: this.state.dataSource.cloneWithRows(newAnnotations),
    });
  }

  renderField(field) {
    console.log(field);
    let color = (field.active == true)?'blue':'yellow';

    return (
      <TouchableOpacity onPress={this.handleClick.bind(this,field)}>
        <Text style={{backgroundColor:color,borderWidth:1}}>{field.title}</Text>
      </TouchableOpacity>
    );
  }

  render() {
    return (
      <View style={{flex:1,flexDirection:'column',alignSelf:'stretch'}}>
        <MapView
          style={{flex:0.5,alignSelf:'stretch',borderWidth:1}}
          region={this.state.region}
          annotations={this.state.annotations}
        />
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(field) => this.renderField(field)}
        />
      </View>
    );
  }
}

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

참조URL: https://stackoverflow.com/questions/38270445/you-attempted-to-set-the-key-on-an-object-that-is-meant-to-be-immutable-and-has

반응형