Skip to content

Instantly share code, notes, and snippets.

@pbfrias17 pbfrias17/Hooks.js
Last active Jun 26, 2019

Embed
What would you like to do?
The components used for the SmartLogic React/React-Native Hooks Blogpost
import React, { useEffect } from 'react'
import { Dimensions, Image, StyleSheet } from 'react-native'
const styles = StyleSheet.create({
hook: {
position: 'absolute',
alignSelf: 'center',
resizeMode: 'contain',
width: 150,
height: 300,
top: -70
}
})
export const useHookedEffect = (visible) => {
const SCREEN_HEIGHT = Dimensions.get('window').height
const HIDDEN_TRANSFORM = { transform: [{ translateY: -SCREEN_HEIGHT }] }
const SHOWN_TRANSFORM = { transform: [{ translateY: 0 }] }
const initialTransform = visible ? SHOWN_TRANSFORM : HIDDEN_TRANSFORM
const hookedRef = React.createRef()
useEffect(() => {
const targetTransform = visible ? SHOWN_TRANSFORM : HIDDEN_TRANSFORM
hookedRef.current.transitionTo(targetTransform, 300)
}, [visible])
const HookComponent = () => (
<Image source={{ uri: 'https://jurofishing.com/wp-content/uploads/2017/10/Long-Shank-Red-Series.png' }} style={styles.hook} />
)
return [initialTransform, hookedRef, HookComponent]
}
import React from 'react'
import { View, Text, TouchableWithoutFeedback, TouchableOpacity } from 'react-native'
import styles from './styles/PromptStyles'
export default React.memo((props) => {
const onChoose = (choice) => () => {
props.onSetChoice(choice)
}
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={props.onPressBackdrop}>
<View style={styles.backdrop} />
</TouchableWithoutFeedback>
<View style={styles.contentContainer}>
<Text style={styles.prompt}>{props.prompt}</Text>
{
props.choice.map(choice =>
<TouchableOpacity onPress={onChoose(choice)} style={styles.choice}>
<Text style={styles.choiceText}>{choice.label}</Text>
</TouchableOpacity>
)
}
</View>
</View>
)
})
import React, { useState } from 'react'
import { View, Text, TouchableWithoutFeedback, TouchableOpacity } from 'react-native'
import * as Animatable from 'react-native-animatable'
import { useHookedEffect } from '../lib/Hooks'
import styles from './styles/PromptStyles'
export default React.memo((props) => {
const [selectedChoice, setSelectedChoice] = useState()
const [initialTransform, hookedRef, HookComponent] = useHookedEffect(props.visible)
const onChoose = (choice) => () => {
setSelectedChoice(choice)
}
const onSubmit = () => {
props.onSetChoice(selectedChoice)
}
return (
<Animatable.View useNativeDriver ref={hookedRef} style={[styles.container, initialTransform]}>
<TouchableWithoutFeedback onPress={props.onPressBackdrop}>
<View style={styles.backdrop} />
</TouchableWithoutFeedback>
<HookComponent />
<View style={styles.contentContainer}>
<Text style={styles.prompt}>{props.prompt}</Text>
{
props.choice.map(choice => {
const buttonStyle = (selectedChoice && choice.value === selectedChoice.value)
? [styles.choice, styles.selected]
: styles.choice
return (
<TouchableOpacity onPress={onChoose(choice)} style={buttonStyle}>
<Text style={styles.choiceText}>{choice.label}</Text>
</TouchableOpacity>
)
})
}
<TouchableOpacity onPress={onSubmit} style={styles.submit}>
<Text style={styles.submitText}>SUBMIT</Text>
</TouchableOpacity>
</View>
</Animatable.View>
)
})
import React, { useState } from 'react'
import { View, Text, TouchableWithoutFeedback, TouchableOpacity } from 'react-native'
import styles from './styles/PromptStyles'
export default React.memo((props) => {
const [selectedChoice, setSelectedChoice] = useState()
const onChoose = (choice) => () => {
setSelectedChoice(choice)
}
const onSubmit = () => {
props.onSetChoice(selectedChoice)
}
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={props.onPressBackdrop}>
<View style={styles.backdrop} />
</TouchableWithoutFeedback>
<View style={styles.contentContainer}>
<Text style={styles.prompt}>{props.prompt}</Text>
{
props.choice.map(choice => {
const buttonStyle = (selectedChoice && choice.value === selectedChoice.value)
? [styles.choice, styles.selected]
: styles.choice
return (
<TouchableOpacity onPress={onChoose(choice)} style={buttonStyle}>
<Text style={styles.choiceText}>{choice.label}</Text>
</TouchableOpacity>
)
})
}
<TouchableOpacity onPress={onSubmit} style={styles.submit}>
<Text style={styles.submitText}>SUBMIT</Text>
</TouchableOpacity>
</View>
</View>
)
})
import React, { PureComponent } from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
import styles from './styles/ScreenStyles'
import Prompt from '../components/Prompt'
import PromptWithState from '../components/PromptWithState'
import PromptFinal from '../components/PromptFinal'
import HookedFish from '../components/HookedFish'
export default class extends PureComponent {
choices = [
{ value: 0, label: 'Scary' },
{ value: 1, label: 'Pointy' },
{ value: 2, label: 'Great!' }
]
state = {
selectedChoice: null,
showPrompt: false
}
render () {
const { selectedChoice, showPrompt } = this.state
return (
<View style={styles.container}>
<Text style={styles.text}>
{selectedChoice ? `You think hooks are ${selectedChoice.label}` : 'Your feelings towards hooks are uncertain'}
</Text>
<TouchableOpacity onPress={() => this.setState({ showPrompt: true })} style={styles.button}>
<Text style={styles.buttonText}>Show Prompt</Text>
</TouchableOpacity>
{/* Before adding animation this is how we would toggle the prompt */}
{/* {
showPrompt &&
<PromptWithState
prompt='Hooks are:'
choice={this.choices}
onSetChoice={choice => this.setState({ selectedChoice: choice, showPrompt: false })}
onPressBackdrop={() => this.setState({ showPrompt: false })}
/>
} */}
{/* After adding animation the prompt will always be 'mounted', but will be controlled by props.visible */}
<PromptFinal
prompt='Hooks are:'
visible={showPrompt}
choice={this.choices}
onSetChoice={choice => this.setState({ selectedChoice: choice, showPrompt: false })}
onPressBackdrop={() => this.setState({ showPrompt: false })}
/>
{/* <HookedFish visible={showPrompt} /> */}
</View>
)
}
}
import { StyleSheet } from 'react-native'
export default StyleSheet.create({
button: {
padding: 10,
alignItems: 'center',
borderColor: 'grey',
borderWidth: 3,
borderRadius: 10
},
buttonText: {
fontSize: 24
},
container: {
flex: 1,
padding: 40
},
text: {
fontSize: 24,
alignSelf: 'center',
textAlign: 'center',
marginVertical: '30%'
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.