首页 > 解决方案 > React Native: Having different states per dynamic view

问题描述

What my app does is getting data from an API and post a list of events that are happening each with their own unique information but its all done dynamically and they each follow the same view/style/container etc. I have an icon (notification icon) that when a user taps on it, it changes the icon for that specific event (shown in the images). But what I have now is that all the icons change for each event instead of the individual one.

export default class LaunchingScreen extends React.Component{

  constructor(props) {
    super(props);  
    this.state = {
      NotifIcon: "md-notifications-off",
      isLoading: true,
      dataSource: null,
      refreshing: false,
      isActive: true,

    };
  }
      //Gets data from API 
      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);
          });
      }
      //Renders Screen
      render() {
        //Refresh if statement
        if (this.state.isLoading) {
          return (
            <View style={styles.container}>
              <ActivityIndicator />
            </View>
          );
        } 
        else{

          //Launches is what its called on later to display what is being said in launches
          let launches = this.state.dataSource.map((item, key) => {

          return (
            <View key={key} style={styles.container}>
              <Image
                style={{ width: "100%", height: 475, borderRadius: 10, opacity: 1 }}
                source={RocketImage}
                />
                <View style={styles.iconBar}>
                  <Entypo
                    name="video-camera"
                    color={"white"}
                    size={30}
                    style={styles.VideoIcon}
                    onPress={() => {
                      if (item.vidURLs.length > 0) {
                        Linking.openURL(item.vidURLs[0]);
                      } else if (item.vidURLs.length == 0) {
                        Alert.alert("There is no livestream available.");
                      }
                    }}
                  />
                  <Ionicons
                    name={this.state.NotifIcon}
                    color={"white"}
                    size={30}
                    style={styles.NotifIcon}
                      onPress={() => {
                        Vibration.vibrate()
                        if(this.state.isActive){
                          PushNotificationIOS.scheduleLocalNotification({
                            alertTitle: "Launching Soon!",
                            alertBody: FullName + " is going to launch soon! Get the livestream here!",
                            fireDate: new Date(Date.now() + (60 * 1000)) // in 30 mins
                          });
                          this.setState({
                            NotifIcon : "md-notifications"
                          });
                          this.state.isActive = false;
                        }
                        else if(this.state.isActive != true){
                          PushNotificationIOS.cancelLocalNotifications();
                          this.setState({
                            NotifIcon : "md-notifications-off"
                          });
                          this.state.isActive = true;
                        }

                    }}
                  />

                </View>

How would I go about trying to make each state/icon individual for each event? Thanks!

Images: https://imgur.com/a/8tpczqs

标签: reactjsapireact-nativestate

解决方案


Ok they all change because all the "notification" icons, are using the same state, to fix this, you will need to make them into one individual custom component with their own state management. This menas create a new Bell.js file with content like this:

import * as React from 'react';
//import things here
export default class Bell extends React.Component {
  constructor() {
    super();
    this.state = {
      isActive: true,
      NotifIcon:"md-notifications-off"
    };
  }

  render() {
    return (
      <Ionicons
                    name={this.state.NotifIcon}
                    color={"white"}
                    size={30}
                    style={styles.NotifIcon}
                      onPress={() => {
                        Vibration.vibrate()
                        if(this.state.isActive){
                          PushNotificationIOS.scheduleLocalNotification({
                            alertTitle: "Launching Soon!",
                            alertBody: this.props.FullName + " is going to launch soon! Get the livestream here!",
                            fireDate: new Date(Date.now() + (60 * 1000)) // in 30 mins
                          });
                          this.setState({
                            NotifIcon : "md-notifications"
                          });
                          this.state.isActive = false;
                        }
                        else if(this.state.isActive != true){
                          PushNotificationIOS.cancelLocalNotifications();
                          this.setState({
                            NotifIcon : "md-notifications-off"
                          });
                          //if you want to do something or notify the app , you can use something like this.props.onTap 
                          this.state.isActive = true;
                        }

                    }}
                  />
    );
  }
}

And then you just import the component and use it

import NotificationBell from './Bell'

and to use it you just place this

<View style={styles.iconBar}>
                  <Entypo
                    name="video-camera"
                    color={"white"}
                    size={30}
                    style={styles.VideoIcon}
                    onPress={() => {
                      if (item.vidURLs.length > 0) {
                        Linking.openURL(item.vidURLs[0]);
                      } else if (item.vidURLs.length == 0) {
                        Alert.alert("There is no livestream available.");
                      }
                    }}
                  />
                  <NotificationBell FullName='Here you place the name' onTap={()=>{this.doSomething()}}/>

                </View>

You can find how to create custom components and the way of handling communication / sending "props" in this awesome Medium Article


推荐阅读