Несколько компонентов с одинаковым именем состояния, как изменить одно состояние одного компонента, не затрагивая другие? - PullRequest
0 голосов
/ 21 января 2019

В моей собственной программе реагирования у меня есть компонент (Bell), который вызывается для каждого элемента / списка, вызываемого из API. Колокольчик используется, чтобы сделать уведомление (и отменить его) для прессы, и я сделал состояние (isBellActive), чтобы определить, был ли колокол включен или нет. Если это так, isBellActive имеет значение true и false в противном случае. Я храню данные через asyncStorage.

Проблема, с которой я столкнулся, заключается в том, что если я изменю состояние одного звонка (для одного элемента / списка), а затем закрою приложение и перезапущу, то это изменение состояния этого звонка повлияет на состояние isBellActive всех остальных компонентов звонка. Как сделать так, чтобы состояние (даже если все они имеют одно и то же имя) сохранялось для одного конкретного элемента / списка

Класс компонентов колокола

export default class Bell extends React.Component {
  constructor(props) {
    super(props);  
    this.state = {
      isBellActive:  null,

    };
  }

  componentDidMount = ()=>{
    AsyncStorage.getItem('isBellActive').then(value => this.setState({ isBellActive: JSON.parse(value) }));
  }

  setTrue(){
    AsyncStorage.setItem('isBellActive', JSON.stringify(true)).then(() => {
      this.setState({ isBellActive: true});
    });
  }

  setFalse(){
    AsyncStorage.setItem('isBellActive', JSON.stringify(false)).then(() => {
      this.setState({ isBellActive: false});
    });
  }

  render() {
     return (
      <Ionicons

        name={this.state.isBellActive? "md-notifications":"md-notifications-off"}
        color={"white"}
        size={30}
        style={styles.NotifIcon}
        onPress={() => {       
            Vibration.vibrate()
             if(this.state.isBellActive == false){             
                  PushNotificationIOS.scheduleLocalNotification({
                    userInfo:{
                      ID: this.state.ID
                    },
                    alertTitle: "Launching Soon:",
                    alertBody: this.state.alertBody,
                    fireDate: this.state.fireDate // in 30 mins
                    });
                    this.setTrue()
                    this.setState({Key:true})
                  }
                  else if(this.state.isBellActive != false){
                    PushNotificationIOS.cancelLocalNotifications({ID:this.state.ID});
                    this.setFalse()
                  }
                }
            }
         }}
       />
    );
  }
}

Класс, который вызывает Компонент

export default class LaunchingScreen extends React.Component{
 let launches = this.state.dataSource.map((item, key) => {
   ..
   <View>
    ..
    <Bell />
    ..
   </View>
     ..
  }
}

UPDATE Это класс, который вызывает компоненты, он получает JSON со всей информацией:

componentDidMount(){
    return fetch("https://launchlibrary.net/1.4/launch/next/20")
      .then(response => response.json())
      .then(responseJson => {
        this.setState({
          isLoading: false,
          dataSource: responseJson.launches
        }); 
      })
      .catch(error => {
        console.log(error);
      });
  }

Picture of an item and it's bell

1 Ответ

0 голосов
/ 21 января 2019

В соответствии с ответом от общего API, похоже, что свойство id уникально, и вы можете использовать это свойство для уникального определения key для Bell компонента и использовать это key для хранения / получить данные из AsyncStorage. Пожалуйста, рассмотрите следующие фрагменты кода

Изменить LaunchingScreen , чтобы добавить key={item.id}

export default class LaunchingScreen extends React.Component{
  let launches = this.state.dataSource.map((item, key) => {
    ..
    <View>
    ..
    <Bell key={item.id}/>
    ..
    </View>
    ..
  }
}

Теперь в компоненте Bell используйте свойство key для доступа к данным из AsyncStorage

export default class Bell extends React.Component {
  constructor(props) {
    super(props);  
    this.state = {
      isBellActive:  null
    };
    this.accessKey = `${props.key}-isBellActive`;
  }

  componentDidMount = ()=>{
    AsyncStorage.getItem(this.accessKey).then(value => this.setState({ isBellActive: JSON.parse(value) }));
  }

  setTrue(){
    AsyncStorage.setItem(this.accessKey, JSON.stringify(true)).then(() => {
      this.setState({ isBellActive: true});
    });
  }

  setFalse(){
    AsyncStorage.setItem(this.accessKey, JSON.stringify(false)).then(() => {
      this.setState({ isBellActive: false});
    });
  }

  render() {
     return (
      <Ionicons

        name={this.state.isBellActive? "md-notifications":"md-notifications-off"}
        color={"white"}
        size={30}
        style={styles.NotifIcon}
        onPress={() => {       
            Vibration.vibrate()
             if(this.state.isBellActive == false){             
                  PushNotificationIOS.scheduleLocalNotification({
                    userInfo:{
                      ID: this.state.ID
                    },
                    alertTitle: "Launching Soon:",
                    alertBody: this.state.alertBody,
                    fireDate: this.state.fireDate // in 30 mins
                    });
                    this.setTrue()
                    this.setState({Key:true})
                  }
                  else if(this.state.isBellActive != false){
                    PushNotificationIOS.cancelLocalNotifications({ID:this.state.ID});
                    this.setFalse()
                  }
                }
            }
         }}
       />
    );
  }
}

В вышеуказанном компоненте мы сначала определяем ключ доступа, используя this.accessKey = ${props.key}-isBellActive; , а затем используем this.accessKey вместо isBellActive.

Надеюсь, это поможет !!!

...