We hired InfiniteRed, instead of a less expensive contract-developer option, because we were promised a senior-level engineer and React Native expert.
Rather than learning and making progress with solid code from the InfiniteRed expert, we found ourselves continually surprised by the lack of code quality. Once we realized the code from our assigned expert was not of expert or senior level, we decided to wind down the contract.
Since parting with InfiniteRed, we regularly find bugs and surprising bits of code to clean up originating from our assigned expert.
Below are some of bugs and poor quality code which was committed to our repo by our assigned InfiniteRed expert. There are more examples, but this should be sufficient to prove that we were not assigned an expert or senior-level engineer.
This first example was the last straw in deciding to stop working with InfiniteRed.
See this commit at the very beginning of our work where a timeout hack was added to try to get around the asynchronous nature of setState.
validateForm = () => {
// Why is this in a setTimeout? Because setState, which invokes this
// in a callback from changes to the email and password fields, is
// batched and executed asynchronously. Wrapping the form validation in
// a setTimeout ensures it gets executed after setState has done its job.
setTimeout(() => {
this.setState({formValid: this.validation()})
}, 10)
}
This is the diff to remove the hack.
$ git show 094bf9c3fd18e3563b0032322f0e3fd42c8a3a8f
commit 094bf9c3fd18e3563b0032322f0e3fd42c8a3a8f
Author: Beau Smith <beau@beausmith.com>
Date: Mon Feb 27 12:32:55 2017 -0800
Use actual interpunct symbol instead of HTML entity.
http://middot.net/
diff --git a/App/Containers/LandingScreen.js b/App/Containers/LandingScreen.js
index 4bb551c..ae05bca 100644
--- a/App/Containers/LandingScreen.js
+++ b/App/Containers/LandingScreen.js
@@ -4,7 +4,6 @@ import React from 'react'
import { View, Text, Image } from 'react-native'
import { Images } from '../Themes'
import Roundedbutton from '../Components/RoundedButton'
-import HTMLView from 'react-native-htmlview'
import { Actions as NavigationActions } from 'react-native-router-flux'
// Styles
@@ -20,15 +19,12 @@ class LandingScreen extends React.Component {
}
render () {
- const htmlContent = '<p>Evidence-based · Top therapists · Smart tools</p>'
return (
<View style={styles.container}>
<View>
<Image source={Images.kipLogoNobackground} style={styles.kipLogo} />
<Text style={styles.therapy}>Therapy how it should be.</Text>
- <View style={styles.evidenceBased}>
- <HTMLView stylesheet={styles} value={htmlContent} />
- </View>
+ <Text style={styles.evidenceBased}>Evidence-based · Top therapists · Smart tools</Text>
</View>
<View style={styles.landingScreenBottom}>
<Text style={styles.cities}>San Francisco - Oakland - Silicon Valley</Text>
diff --git a/App/Containers/Styles/LandingScreenStyle.js b/App/Containers/Styles/LandingScreenStyle.js
index 10c33b7..637040d 100644
--- a/App/Containers/Styles/LandingScreenStyle.js
+++ b/App/Containers/Styles/LandingScreenStyle.js
@@ -25,20 +25,9 @@ export default StyleSheet.create({
alignSelf: 'center'
},
evidenceBased: {
- alignSelf: 'center'
- },
- // The 'p' key styles the p tag in HTMLView, which has its stylesheet tag pointing to this file.
- // Note that the HTMLView attribute is 'stylesheet', not 'style'!!!
- p: {
color: Colors.mediumDarkened5Percent,
- ...Fonts.style.h5
- },
- middot: {
- width: 8,
- height: 8,
- resizeMode: 'contain',
- marginTop: -1,
- marginLeft: 2
+ ...Fonts.style.h5,
+ alignSelf: 'center'
},
landingScreenBottom: {
marginBottom: Metrics.doubleBaseMargin * 2
See Preventing Component from Rendering
if (!readyToRender) {
return (<View />)
}
vs this:
if (!readyToRender) {
return null
}
In DailyCheckinReminder.js
there is a TextInput
for entering the desired text message.
Problems with the component:
- Using
placeholder
for the current/saved value, instead thevalue
attribute and of a constantplaceholder
value. - Not using a
value
attribute for the user's value. - Not using state to manage the value.
- Not debouncing a callback which fires on every keystroke.
this commit: https://github.com/HelloKip/kip-mobile-app/commit/55c0ae91158076d66f472f1cfe74221fee9daa7e
<TextInput
multiline
blurOnSubmit
placeholderTextColor={Colors.mediumWell}
style={styles.textInput}
returnKeyType='done'
autoCapitalize='none'
autoCorrect={false}
underlineColorAndroid='transparent'
onSubmitEditing={this.updateReminderText}
placeholder={reminderText} />
this.updateReminderText
is called when onSubmitEditing
is invoked, but that almost never happens, because per React Native docs:
onSubmitEditing: Callback that is called when the text input's submit button is pressed. Invalid if multiline={true} is specified.
this commit: https://github.com/HelloKip/kip-mobile-app/commit/55c0ae91158076d66f472f1cfe74221fee9daa7e
The DailyCheckinReminderSetTime
component doesn't show up on Android due to the way the views on the screen were set up:
<ScrollView style={[styles.container, {height: visibleHeight}]}>
Code was written to change the height of the outer-most View
element using listeners. Adding another element to the content of the view to force the content to be taller shows that the logic to adjust the height to avoid the doesn't work.
This code was copy/pasted into a number of different Container screens.
(Additionally, it's questionable as to why the KeyboardAvoidingView
built into react-native
was not used.)
If the code worked, the bottom of this red-bordered box would be visible when the keyboard is visible: