├── .gitignore ├── README.md ├── index.js ├── package.json └── react-native-component-inview.gif /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-component-inview 2 | 3 | A React Native wrapper to check whether a component is in the view port to track impressions and clicks 4 | 5 | ![demo](https://github.com/changey/react-native-component-inview/blob/master/react-native-component-inview.gif) 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm i --save react-native-component-inview # npm syntax 11 | yarn add react-native-component-inview --save # yarn syntax 12 | ``` 13 | 14 | ## Example 15 | 16 | ``` 17 | import InView from 'react-native-component-inview' 18 | 19 | const [isInView, setIsInView] = useState(false) 20 | 21 | const checkVisible = (isVisible:boolean) => { 22 | if (isVisible){ 23 | setIsInView(isVisible) 24 | } else { 25 | setIsInView(isVisible) 26 | } 27 | } 28 | 29 | 30 | this.checkVisible(isVisible)}> 31 | 32 | yay 33 | 34 | 35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Dimensions, View } from 'react-native' 3 | 4 | export interface Iprops { 5 | disabled: boolean 6 | } 7 | 8 | const InViewPort = class extends Component { 9 | constructor(props: Iprops) { 10 | super(props) 11 | this.state = { rectTop: 0, rectBottom: 0 } 12 | } 13 | 14 | componentDidMount() { 15 | if (!this.props.disabled) { 16 | this.startWatching() 17 | } 18 | } 19 | 20 | componentWillUnmount() { 21 | this.stopWatching() 22 | } 23 | 24 | UNSAFE_componentWillReceiveProps(nextProps) { 25 | if (nextProps.disabled) { 26 | this.stopWatching() 27 | } else { 28 | this.lastValue = null 29 | this.startWatching() 30 | } 31 | } 32 | 33 | startWatching() { 34 | if (this.interval) { 35 | return 36 | } 37 | this.interval = setInterval(() => { 38 | if (!this.myview) { 39 | return 40 | } 41 | this.myview.measure((x, y, width, height, pageX, pageY) => { 42 | this.setState({ 43 | rectTop: pageY, 44 | rectBottom: pageY + height, 45 | rectWidth: pageX + width 46 | }) 47 | }) 48 | this.isInViewPort() 49 | }, this.props.delay || 100) 50 | } 51 | 52 | stopWatching() { 53 | this.interval = clearInterval(this.interval) 54 | } 55 | 56 | isInViewPort() { 57 | const window = Dimensions.get('window') 58 | const isVisible = 59 | this.state.rectBottom !== 0 && 60 | this.state.rectTop >= 0 && 61 | this.state.rectBottom <= window.height && 62 | this.state.rectWidth > 0 && 63 | this.state.rectWidth <= window.width 64 | if (this.lastValue !== isVisible) { 65 | this.lastValue = isVisible 66 | this.props.onChange(isVisible) 67 | } 68 | } 69 | 70 | render() { 71 | return ( 72 | { 74 | this.myview = component 75 | }} 76 | {...this.props} 77 | > 78 | {this.props.children} 79 | 80 | ) 81 | } 82 | } 83 | 84 | export default InViewPort 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-component-inview", 3 | "version": "1.0.1", 4 | "description": "Detect if component is in device viewport", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "react-component", 11 | "react-native", 12 | "ios", 13 | "android", 14 | "intersection-observer", 15 | "impressions" 16 | ], 17 | "author": "Eric Chang (http://github.com/changey)", 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/changey/react-native-inview-port.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/changey/react-native-inview-port/issues" 25 | }, 26 | "homepage": "https://github.com/changey/react-native-inview-port#readme" 27 | } 28 | -------------------------------------------------------------------------------- /react-native-component-inview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/changey/react-native-component-inview/e9528842674284b2e5a9f0ce84cafbfc75f2d27d/react-native-component-inview.gif --------------------------------------------------------------------------------