具有相同状态名称的多个组件,如何更改一个组件的一种状态而不影响其他组件?

时间:2019-01-21 02:45:55

标签: react-native async-await components local-storage

在我的本地反应程序中,我有一个组件(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>
     ..
  }
}

更新 这是在调用组件的类中,它获取具有所有信息的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 :(得分:1)

根据您共享的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。< / p>

希望这会有所帮助!