[React Native] Touch Event, Button

2020. 12. 24. 02:41React/React Native

1. 사전 작업

1) header 작업

  • src 폴더 생성
  • src 폴더 하위에 header.js 파일 생성
  • header.js 파일에 코드 작성 (1)
  • App.js 파일에 header.js 파일 import 및 적용 (2)

 

(1)

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const Header = () => (
    <View style={styles.header}>
        <Text>This is header.</Text>
    </View>
)

const styles = StyleSheet.create({
    header: {
        backgroundColor: 'pink',
        alignItems: 'center',
        width: '100%'
      }
})

export default Header;

(2)

import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import Header from './src/header'; // header.js 파일에서 Header로 export

class App extends Component {
  render() {
    return (
      <View style={styles.mainView}>
        <Header/>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  mainView: {
    flex: 1,
    backgroundColor: 'white', 
    paddingTop: 50, 
    alignItems: 'center',
    justifyContent: 'center'
  },

  subView: {
    backgroundColor: 'yellow',
    marginBottom: 10
  },
  
  mainText: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'red',
    padding: 20
  }
})

export default App;

2) State 작업

header의 작업에 State를 추가해준다.

...

const Header = (props) => (
    <View style={styles.header}>
        <Text>{props.name}</Text>
    </View>
)

...
...

class App extends Component {

  state = {
    appName: 'My First App'
  }

  render() {
    return (
      <View style={styles.mainView}>
        <Header name={this.state.appName}></Header>
      </View>
    )
  }
}

...

사전 작업

 

 

 

2. Touch Event

1) View Touch

Touch Event는 공식 문서(reactnative.dev/docs/touchableopacity)에 나온 TouchableOpacity를 이용하여 구현할 수 있다.

공식 문서

사용법은 간단한다. 생성한 header.js 파일에 TouchableOpacity를 추가해주고, onPress 속성을 이용하여 이벤트를 발생시킬 수 있다.

import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';

const Header = (props) => (
    <TouchableOpacity style={styles.header} onPress={() => alert('alert')}>

        <View>
            <Text>{props.name}</Text>
        </View>

    </TouchableOpacity>
)

const styles = StyleSheet.create({
    header: {
        backgroundColor: 'pink',
        alignItems: 'center',
        width: '100%'
      }
})

export default Header;

TouchableOpacity에는 다양한 속성(onPress, onLongPress, onPressIn, ... 등)들이 있다. 예를 들면, TouchableOpacity이 상속받는 TouchableWithoutFeedback을 이용하여 투명성을 제거해줄 수 있다. 단, View에 아무런 변화를 일으키지 않기에 Style을 View에 적용해준다. (마찬가지로 TouchableWithoutFeedback 또한 다양한 속성들이 존재)

import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity, TouchableWithoutFeedback } from 'react-native';

const Header = (props) => (
    <TouchableWithoutFeedback onPress={() => alert('alert')}>

        <View style={styles.header}>
            <Text>{props.name}</Text>
        </View>

    </TouchableWithoutFeedback>
)

const styles = StyleSheet.create({
    header: {
        backgroundColor: 'pink',
        alignItems: 'center',
        width: '100%'
      }
})

export default Header;

TouchableWithoutFeedback

2) Button Touch

Button을 이용하여 숫자를 추가하는 로직에서 주의깊게 봐야하는 점은 다음과 같다.

  • State 변수 전달
  • App.js - onAddRandomNum, onNumDelete 함수의 생성 및 전달 (prevState 주의) (1)
  • generator.js Button 생성 (2)
  • numList.js - props로 전달받은 배열의 Arrow Function (map) (3)

 

(1)

import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import Header from './src/header';
import Generator from './src/generator';
import NumList from './src/numList';

class App extends Component {

  state = {
    appName: 'My First App',
    random: [36, 999]
  }

  onAddRandomNum = () => {
    // (0 ~ 1사이의 임의 소수 * 100)의 소수점을 버린 값
    const randomNum = Math.floor(Math.random()*100) + 1;
    this.setState(prevState => {
      return {
        random: [...prevState.random, randomNum]
      }
    })
  }

  onNumDelete = (position) => {
    // random 배열에서 전달받은 인덱스를 제외한 나머지 요소 값들을 새로운 배열에 복사하고 그 배열을 업데이트
    const newArray = this.state.random.filter((num, index) => {
      return position != index;
    })
    this.setState({
      random: newArray
    })
  }

  render() {
    return (
      <View style={styles.mainView}>
        <Header name={this.state.appName}></Header>
        
        <View>
          <Text 
            style={styles.mainText} 
            onPress={()=>alert('text alert')}>
            Hello World
          </Text>
        </View>
        
        <Generator add={this.onAddRandomNum}/>
        <NumList 
          num={this.state.random}
          delete={this.onNumDelete}
        />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  mainView: {
    flex: 1,
    backgroundColor: 'white', 
    paddingTop: 50, 
    alignItems: 'center',
    // justifyContent: 'center'
  },

  subView: {
    backgroundColor: 'yellow',
    marginBottom: 10
  },

  anotherSubView: {
    backgroundColor: 'yellow',
    marginBottom: 10,
    alignItems: 'center',
    justifyContent: 'center'
  },
  
  mainText: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'red',
    padding: 20
  }
})

export default App;

(2)

import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';

const Generator = (props) => {
    return (
        <View style={styles.generator}>
            <Button 
                title="Add Number"
                onPress={()=>props.add()}/>
        </View>
    )
}

const styles = StyleSheet.create({
    generator: {
        backgroundColor: '#D197CF',
        alignItems: 'center',
        padding: 5,
        width: '100%'
    }
})

export default Generator;

(3)

import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';

const NumList = (props) => {
    return (
        props.num.map((item, idx) =>(
            <TouchableOpacity 
                style={styles.numList} 
                key={idx}
                onPress={()=>props.delete(idx)}
            >

                <Text>{item}</Text>

            </TouchableOpacity>
        ))
        
    )
}

const styles = StyleSheet.create({
    numList: {
        backgroundColor: '#CECECE',
        alignItems: 'center',
        padding: 5,
        width: '100%',
        marginTop: 5
    }
})

export default NumList;
728x90