Alert.alert() 에 대한 질문이 있는데요

Alert.alert() 안에 타이틀 글을 넣고 타이틀 아래에 데이터를 표시하고 싶은데요

  • 오류가 떠서 어느부분이 문제인지 어떻게 해결해야 하는지 알려주시면 감사하겠습니다.

import React, { Component } from "react";
import {
TouchableOpacity,
Text,
View,
ListView,
TouchableHighlight,
Dimensions,
Image,
Animated,
StyleSheet,
TextInput,
ImageBackground,
Alert
} from "react-native";
import { SearchBar, ListItem, List } from "react-native-elements";
import Ionicons from "@expo/vector-icons/Ionicons";
import sitterdata from "../components/sitterdata";

const { width, height } = Dimensions.get("window");

/*
const datas = [
{
  name: "Registers",
  route: "Registers",
  icon: "phone-portrait",
  bg: "#C5F442"
},
{
  name: "PetSitters",
  route: "PetSitters",
  icon: "easel",
  bg: "#C5F442"
}
];
*/

export default class PetSitters extends Component {
constructor(props) {
  super(props);
  const ds = new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2
  });
  this.state = {
    dataSource: ds.cloneWithRows(sitterdata),
    refreshing: false
  };
}

static navigationOptions = ({ navigation }) => {
  return {
    title: "Pet Sitters",
    headerLeft: (
      <TouchableOpacity
        style={{ padding: 5, paddingRight: 15 }}
        //dataArray={datas}
        onPress={() => navigation.openDrawer()}
      >
        <Ionicons name={"ios-menu"} size={35} color={"#fff"} />
      </TouchableOpacity>
    ),

    headerRight: (
      <TouchableOpacity
        style={{ padding: 5, paddingRight: 15 }}
        onPress={() => navigation.navigate("Add")}
      >
        <Ionicons name={"ios-add"} size={35} color={"#fff"} />
      </TouchableOpacity>
    )
  };
};

showAlert(navigation) {
  Alert.alert(
    "이 펫시터와 거래 하시겠습니까?",
    this.state.dataSource(sitterdata.item.by),
    [
      {
        text: "Cancel",
        onPress: () => console.log("Cancel Pressed"),
        style: "cancel"
      },
      { text: "OK", onPress: () => navigation.navigate("Add") }
    ],
    { cancelable: false }
  );
}

async filterSearch(text) {
  const newData = sitterdata.filter(function(item) {
    const itemData = item.address.toUpperCase();
    const textData = text.toUpperCase();
    return itemData.indexOf(textData) > -1;
  });
  await this.setState({
    dataSource: this.state.dataSource.cloneWithRows(newData),
    text: text
  });
}

renderRow(rowData) {
  return (
    <TouchableHighlight style={styles.containerCell}>
      <View>
        <TouchableOpacity
          onPress={() => this.showAlert(this.props.navigation)}
        >
          <Image
            style={{ width: width, height: 180, resizeMode: "stretch" }}
            source={{ uri: rowData.image }}
          />
        </TouchableOpacity>
        <View style={styles.footerContainer}>
          <View style={styles.imageUser}>
            <Image
              style={styles.imageAvatar}
              source={{ uri: rowData.user }}
            />
          </View>
          <View style={styles.footerTextContainer}>
            <Text style={styles.text}>{rowData.introduce}</Text>
            <Text style={[styles.text, styles.textTitle]}>
              {rowData.address}
            </Text>
            <Text style={[styles.text, styles.textBy]}>By {rowData.by}</Text>
          </View>
        </View>
      </View>
    </TouchableHighlight>
  );
}

render() {
  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.content,
          {
            width: width,
            backgroundColor: "#dfe4ea",
            flex: 1,
            transform: [
              {
                perspective: 450
              }
            ]
          }
        ]}
      >
        <SearchBar
          onChangeText={text => this.filterSearch(text)}
          placeholder={"여기에 입력하세요"}
          value={this.state.text}
          lightTheme
          containerStyle={{}}
        />
        <ListView
          enableEmptySections={true}
          style={styles.listContainer}
          renderRow={this.renderRow.bind(this)}
          dataSource={this.state.dataSource}
        />
      </Animated.View>
    </View>
  );
}
}

위에는 전체 코드이구요 제가 오류가 나는부분은 Alert.alert() 부분입니다.

showAlert(navigation) {
  Alert.alert(
    "이 펫시터와 거래 하시겠습니까?",
    this.state.dataSource(sitterdata.item.by),
    [
      {
        text: "Cancel",
        onPress: () => console.log("Cancel Pressed"),
        style: "cancel"
      },
      { text: "OK", onPress: () => navigation.navigate("Add") }
    ],
    { cancelable: false }
  );
}

이부분에서 오류가 나는데요

    this.state.dataSource(sitterdata.item.by),

일단 에러는 undefined의 속성에 접근하려고 했을 때 문제입니다. 자바스크립트는 undefined의 속성에 접근하면 에러가 납니다. this.sate.sitterdata가 undefeined라는 얘기입니다. 지난 번에도 이 undefined is not an object 에러로 질문 하셨던 것 같은데 이 에러는 자바스크립트에서 가장 흔히 접하게 되는 에러중에 하나이다보니 이에 명확히 이해하고 넘어가시길 바랍니다.

그리고 ListView는 공식 문서에 나와있듯이 Deprecated된 컴포넌트입니다. 이를 사용하기 보다는 FlatList나 SectionList등을 사용하세요.

export default class PetSitters extends Component {
  constructor(props) {
    super(props);
    const ds = new FlatList.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
    this.state = {
      dataSource: ds.cloneWithRows(sitterdata),
      refreshing: false
    };
  }

 render() {
    return (
      <View style={styles.container}>
        <Animated.View
          style={[
            styles.content,
            {
              width: width,
              backgroundColor: "#dfe4ea",
              flex: 1,
              transform: [
                {
                  perspective: 450
                }
              ]
            }
          ]}
        >
          <SearchBar
            onChangeText={text => this.filterSearch(text)}
            placeholder={"여기에 입력하세요"}
            value={this.state.text}
            lightTheme
            containerStyle={{}}
          />
          <FlatList
            enableEmptySections={true}
            style={styles.listContainer}
            renderRow={this.renderRow.bind(this)}
            dataSource={this.state.dataSource}
          />
        </Animated.View>
      </View>

#기존 ListView 에 있던 것을 FlatList로 바꿨는데요.

타입 자체가 에러라고 하는데…형식이 아예 달라서 그런건가요?

사용법이 다릅니다. FlatList 문서를 살펴보세요. 무언가 안될 때는 최 우선적으로 해당 컴포넌트의 공식 문서에 나와있는 설명과 예제를 살펴보세요. 많은 문제를 스스로 해결 할 수 있을 겁니다.

1개의 좋아요
import React, { Component } from "react";
import {
  TouchableOpacity,
  Text,
  View,
  ListView,
  TouchableHighlight,
  Dimensions,
  Image,
  Animated,
  StyleSheet,
  TextInput,
  ImageBackground,
  Alert,
  FlatList
} from "react-native";
import { SearchBar, ListItem, List } from "react-native-elements";
import Ionicons from "@expo/vector-icons/Ionicons";
import sitterdata from "../components/sitterdata";

const { width, height } = Dimensions.get("window");

/*
const datas = [
  {
    name: "Registers",
    route: "Registers",
    icon: "phone-portrait",
    bg: "#C5F442"
  },
  {
    name: "PetSitters",
    route: "PetSitters",
    icon: "easel",
    bg: "#C5F442"
  }
];
*/

export default class PetSitters extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: sitterdata,
      refreshing: false
    };
  }

  static navigationOptions = ({ navigation }) => {
    return {
      title: "Pet Sitters",
      headerLeft: (
        <TouchableOpacity
          style={{ padding: 5, paddingRight: 15 }}
          //dataArray={datas}
          onPress={() => navigation.openDrawer()}
        >
          <Ionicons name={"ios-menu"} size={35} color={"#fff"} />
        </TouchableOpacity>
      ),

      headerRight: (
        <TouchableOpacity
          style={{ padding: 5, paddingRight: 15 }}
          onPress={() => navigation.navigate("Add")}
        >
          <Ionicons name={"ios-add"} size={35} color={"#fff"} />
        </TouchableOpacity>
      )
    };
  };

  showAlert(navigation) {
    Alert.alert(
      "이 펫시터와 거래 하시겠습니까?",
      // this.item.bind(sitterdata.by),
      //"데이터 입력",
      this.state.data(sitterdata.by),
      [
        {
          text: "Cancel",
          onPress: () => console.log("Cancel Pressed"),
          style: "cancel"
        },
        { text: "OK", onPress: () => navigation.navigate("Add") }
      ],
      { cancelable: false }
    );
  }

  async filterSearch(text) {
    const newData = sitterdata.filter(function(item) {
      const itemData = item.address.toUpperCase();
      const textData = text.toUpperCase();
      return itemData.indexOf(textData) > -1;
    });
    await this.setState({
      data: newData,
      text: text
    });
  }

  refreshData = () => {};

  renderItem = ({ item }) => {
    return (
      <TouchableHighlight style={styles.containerCell}>
        <View>
          <TouchableOpacity
            onPress={() => this.showAlert(this.props.navigation)}
          >
            <Image
              style={{
                width: width,
                height: 180,
                resizeMode: "stretch"
              }}
              source={{ uri: item.image }}
            />
          </TouchableOpacity>
          <View style={styles.footerContainer}>
            <View style={styles.imageUser}>
              <Image style={styles.imageAvatar} source={{ uri: item.user }} />
            </View>
            <View style={styles.footerTextContainer}>
              <Text style={styles.text}>{item.introduce}</Text>
              <Text style={[styles.text, styles.textTitle]}>
                {item.address}
              </Text>
              <Text style={[styles.text, styles.textBy]}>By {item.by}</Text>
            </View>
          </View>
        </View>
      </TouchableHighlight>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <Animated.View
          style={[
            styles.content,
            {
              width: width,
              backgroundColor: "#dfe4ea",
              flex: 1,
              transform: [
                {
                  perspective: 450
                }
              ]
            }
          ]}
        >
          <SearchBar
            onChangeText={text => this.filterSearch(text)}
            placeholder={"여기에 입력하세요"}
            value={this.state.text}
            lightTheme
            containerStyle={{}}
          />
          <FlatList
            style={styles.listContainer}
            onRefresh={this.refreshData}
            renderItem={this.renderItem}
            refreshing={this.state.refreshing}
            data={this.state.data}
            keyExtractor={(item, index) => item.address}
          />
        </Animated.View>
      </View>
    );
  }
}

export class AddPetScreen extends Component {
  static navigationOptions = ({ navigation }) => {
    const params = navigation.state.params || {};

    return {
      title: "Add Pet"
    };
  };

  render() {
    return (
      <View style={styles.container2}>
        <View style={{ alignItems: "center", paddingBottom: 50 }}>
          <ImageBackground
            style={{
              width: "100%",
              height: 200,
              justifyContent: "center",
              alignItems: "center",
              backgroundColor: "#fff"
            }}
            source={require("../image/car.png")}
            imageStyle={{ opacity: 0.3 }}
          >
            <Text
              style={{
                fontSize: 30,
                color: "black",
                fontWeight: "bold"
              }}
            >
              차량을 추가해주세요
            </Text>
          </ImageBackground>
        </View>
        <View
          style={{ flexDirection: "row", alignItems: "center", padding: 5 }}
        >
          <Text
            style={{
              fontSize: 18,
              justifyContent: "center",
              alignItems: "center",
              width: "20%",
              color: "#fff"
            }}
          >
            Vin:
          </Text>
          <TextInput
            secureTextEntry={true}
            style={{
              backgroundColor: "#fff",
              borderColor: "#fff",
              borderRadius: 15,
              borderWidth: 2,
              height: 40,
              width: "70%",
              paddingHorizontal: 10
            }}
            placeholder="Vin 넘버를 입력하세요"
          />
        </View>
        <View
          style={{ flexDirection: "row", alignItems: "center", padding: 5 }}
        >
          <Text
            style={{
              fontSize: 18,
              justifyContent: "center",
              alignItems: "center",
              width: "20%",
              color: "#fff"
            }}
          >
            Model:
          </Text>
          <TextInput
            secureTextEntry={true}
            style={{
              backgroundColor: "#fff",
              borderColor: "#fff",
              borderRadius: 15,
              borderWidth: 2,
              height: 40,
              width: "70%",
              paddingHorizontal: 10
            }}
            placeholder="Model명를 입력하세요"
          />
        </View>
        <View
          style={{ flexDirection: "row", alignItems: "center", padding: 5 }}
        >
          <Text
            style={{
              fontSize: 18,
              justifyContent: "center",
              alignItems: "center",
              width: "20%",
              color: "#fff"
            }}
          >
            차량회사:
          </Text>
          <TextInput
            secureTextEntry={true}
            style={{
              backgroundColor: "#fff",
              borderColor: "#fff",
              borderRadius: 15,
              borderWidth: 2,
              height: 40,
              width: "70%",
              paddingHorizontal: 10
            }}
            placeholder="차량 회사명을 입력하세요"
          />
        </View>
        <View
          style={{ flexDirection: "row", alignItems: "center", padding: 5 }}
        >
          <Text
            style={{
              fontSize: 18,
              justifyContent: "center",
              alignItems: "center",
              width: "20%",
              color: "#fff"
            }}
          >
            year:
          </Text>
          <TextInput
            secureTextEntry={true}
            style={{
              backgroundColor: "#fff",
              borderColor: "#fff",
              borderRadius: 15,
              borderWidth: 2,
              height: 40,
              width: "70%",
              paddingHorizontal: 10
            }}
            placeholder="차량 연식을 입력하세요"
            keyboardType="number-pad"
          />
        </View>
        <View
          style={{ flexDirection: "row", alignItems: "center", padding: 5 }}
        >
          <Text
            style={{
              fontSize: 18,
              justifyContent: "center",
              alignItems: "center",
              width: "20%",
              color: "#fff"
            }}
          >
            image:
          </Text>
          <TouchableOpacity
            style={[
              {
                width: "10%",
                height: 30,
                borderColor: "#fff",
                borderWidth: 1,
                borderRadius: 10,
                alignItems: "center",
                justifyContent: "center",
                backgroundColor: "#fff"
              }
            ]}
            onPress={() => {}}
          >
            <Ionicons name={"ios-add"} size={35} color={"gray"} />
          </TouchableOpacity>
        </View>
        <View style={{ alignItems: "center", padding: 5 }}>
          <TouchableOpacity
            style={{
              width: "100%",
              height: 30,
              borderColor: "#fff",
              borderWidth: 1,
              borderRadius: 10,
              alignItems: "center",
              justifyContent: "center",
              backgroundColor: "#74b9ff"
            }}
            onPress={() => {}}
          >
            <Text style={{ fontSize: 17, color: "#fff" }}> 차량 추가</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container2: {
    flex: 1,
    backgroundColor: "#74b9ff",
    justifyContent: "center"
  },
  container: {
    flex: 1,
    backgroundColor: "red",
    justifyContent: "center"
  },
  textInput: {
    height: 30,
    borderWidth: 5,
    borderColor: "red",
    marginTop: 50,
    marginHorizontal: 10
  },
  content: {
    zIndex: 1
  },
  footerContainer: {
    flexDirection: "row",
    paddingHorizontal: 10,
    paddingVertical: 10,
    backgroundColor: "#555566"
  },
  imageAvatar: {
    width: 50,
    height: 50,
    borderRadius: 25,
    marginRight: 5
  },
  listContainer: {
    marginHorizontal: 10
  },
  text: {
    color: "#fff"
  },
  containerCell: {
    marginBottom: 10
  },
  textTitle: {
    fontSize: 13
  },
  textBy: {
    fontSize: 12
  },
  textMenu: {
    fontSize: 20,
    color: "#fff"
  }
});

#기존 ListView 에서 FlatList로 바꾸었는데요

 constructor(props) {
    super(props);
    this.state = {
      data: sitterdata,
      refreshing: false,
      text: sitterdata[0].by
    };
  }
showAlert(navigation) {
    Alert.alert(
      "이 펫시터와 거래 하시겠습니까?",
      // this.item.bind(sitterdata.by),
      //"데이터 입력",
      this.state.text,

      [
        {
          text: "Cancel",
          onPress: () => console.log("Cancel Pressed"),
          style: "cancel"
        },
        { text: "OK", onPress: () => navigation.navigate("Add") }
      ],
      { cancelable: false }
    );
  }

이부분에서 클릭시에 this.state.text가 작동하는건 보았는데요

  • 클릭할때 마다 그림 내용에 맞는 by값을 표현하려면 어떻게 해야되나요?