Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”. This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

1. Introduction

We’ve already written a simple App home page, so let’s start with a few more refinements. It mainly includes: code management, search box function, advertising Banner, commodity list, drop-down refresh, page jump, etc.

2. Code management

I believe you are familiar with it, using Git or Svn can be used, I put the code on gitee (rn_TB link), just for reference.

Rn already created the.gitignore file when the project was created, so after downloading the code on another device, you need to use NPM Install to install dependencies.

2.1 Refactoring Code

We’ve already used StyleSheet, which is used to put the style configuration of a control in one place, just like a CSS file, basically

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },
  input: {
    flex: 1,
    borderColor: 'gray',
    borderWidth: 2,
    borderRadius: 10
  }
)};
Copy the code

The format is key-value, and styles.container can be used. Repeated style usage in code can be extracted into the StyleSheet.

Part of the banner code style refactoring:

return ( <View style={styles.ad_banner}> <ScrollView horizontal={true} pagingEnabled={true} showsHorizontalScrollIndicator={false} ref = {com => this._banner = com} > <TouchableHighlight onPress={() => { Alert. Alert (' click banner', null, null); }}> <Image style={{width:Dimensions.get('window').width, height: 180}} source={image_list.img1}/> </TouchableHighlight> <TouchableHighlight onPress={() => {Alert. Alert (' click banner', null, null); }}> <Image style={{width:Dimensions.get('window').width, height: 180}} source={image_list.img2}/> </TouchableHighlight> <TouchableHighlight onPress={() => {Alert. Alert (' click banner', null, null); }}> <Image style={{width:Dimensions.get('window').width, height: 180}} source={image_list.img3}/> </TouchableHighlight> </ScrollView> </View> );Copy the code

Modify in code:

const ScreenWidth = Dimensions.get('window').width; // Const styles = StyleSheet. Create ({... advContent: { width: ScreenWidth, height: 180 } ... }); return ( <View style={styles.ad_banner}> <ScrollView horizontal={true} pagingEnabled={true} showsHorizontalScrollIndicator={false} ref = {com => this._banner = com} > <TouchableHighlight onPress={() => { Alert. Alert (' click banner', null, null); }}> <Image style={styles.advContent} source={image_list.img1}/> </TouchableHighlight> <TouchableHighlight onPress={() => Alert. Alert (' click banner', null, null); }}> <Image style={styles.advContent} source={image_list.img2}/> </TouchableHighlight> <TouchableHighlight onPress={() => Alert. Alert (' click banner', null, null); }}> <Image style={styles.advContent} source={image_list.img3}/> </TouchableHighlight> </ScrollView> </View> );Copy the code

TouchableHighlight in the banner is mostly repetitive, with only a few differences, which can be further simplified using the MAP () method in JS, similar to the for in operation in Java.

// Define advertisement data const Advertisements = [{title: 'advertisement 1', SRC: image_list.img1}, {title:' advertisement 2', SRC: image_list.img2}, {title: 'ad3 ', SRC: image_list.img3}]; Return (<View style={styles.ad_banner}> <ScrollView horizontal={true} pagingEnabled={true}) showsHorizontalScrollIndicator={false} ref = {com => this._banner = com} > {Advertisements.map((adv, <TouchableHighlight key={index} onPress={() => Alert. Alert (' click banner:' + index, null, null)}> <Image style={styles.advContent} source={adv.src}/> </TouchableHighlight> ); })} </ScrollView> </View> );Copy the code

Note: Key ={index} in TouchableHighlight cannot be omitted

There is much less code and later you can change the Banner directly by modifying the Advertisements value.

3. Search box function -TextInput

After clicking the search button, you can search according to the input content. First of all, you need to obtain the input content. Here, you need to use two knowledge points

  • You can listen for text changes using the onChangeText method in TextInput
  • Use useState to save the contents of the text

The concrete implementation is:

const SearchBar = () => { const [searchText, setSearchText] = useState(''); Return (<View style={styles.search_bar}> <TextInput style={styles.input} placeholder=" search "onChangeText={(text) => { setSearchText(text); {searchText}</TextInput> <Button onPress={() => {Alert. Alert (" input: "+ searchText, null, null); </Button> </View>); }Copy the code

Effect:

4. The banner indicator

General advertising controls will add an indicator, used to mark the current display of the number. We can be lazy and use the text symbol • to represent the dot as follows:

// Const styles = StyleSheet. Create ({... Indicator: {width: ScreenWidth, height: 20, backgroundColor: 'rgba(0,0,0,0)', alignItems: 'center', justifyContent: 'center', top: 150, position: 'absolute', flexDirection: 'row' } }); return ( <View style={styles.ad_banner}> <ScrollView horizontal={true} pagingEnabled={true} showsHorizontalScrollIndicator={false} ref = {com => this._banner = com} > {Advertisements.map((adv, <TouchableHighlight key={index} onPress={() => Alert. Alert (' click banner:' + index, null, null)}> <Image style={styles.advContent} source={adv.src}/> </TouchableHighlight> ); })} </ScrollView> <View style={[styles.indicator]}> {Advertisements.map((_, index) => { return ( <Text key={index} style={[(index === pageNumber) ? {color: 'orange'} : {color: 'white'}, {fontSize: 24}]}> • </Text>); })} </View> </View> ); };Copy the code

Effect:

5. Item list -FlatList+Refresh

We changed the product list to the common format of ListView in Android, icon on the left and Text on the right. The changes are as follows:

// Const styles = StyleSheet. Create ({... product_list: { flex: 1, justifyContent: 'center' }, product_item: { padding: 10, fontSize: 18, height: 44, justifyContent: 'flex-start', flexDirection: 'row', alignItems: 'center' }, product_img: { height: 40, width: 40, borderWidth: 0.5, borderColor: 'gray'}... }); const Products = () => { var data = []; for (var i = 0; i < 100; I++) {data. Push ({key: I, the title: "goods" + I, desc: "this is the description"}); } _renderImte = (item) => { return ( <View style={styles.product_item}> <Image style={styles.product_img} source={require('./images/product_icon.png')}/> <View> <Text >{item.title}</Text> <Text >{item.desc}</Text> </View> </View> ); }; return ( <View style={styles.product_list}> <FlatList style={{flex: 1}} data={data} renderItem={({item}) => this._renderImte(item)}/> </View> ); }Copy the code

Extract renderItem into a function that handles the View of the item and add the image reference to the left.

The flatList also provides the implementation of Header, Footer, SeparateLine, etc., as follows:

_seperateLine = () => { return ( <View style={{height: 1, backgroundColor: 'purple'}}></View> ); }; _itemHeader = () => {return (<Text style={{borderColor: 'red', borderWidth: 1}}> This is Header</Text>); }; _itemFooter = () => {return (<Text style={{borderColor: 'yellow', borderWidth: 1}}> This is Footer</Text>); }; return ( <View style={styles.product_list}> <FlatList style={{flex: 1}} data={data} renderItem={({item}) => this._renderImte(item)} ItemSeparatorComponent={this._seperateLine} ListHeaderComponent={this._itemHeader} ListFooterComponent={this._itemFooter}/> </View> );Copy the code

Effect:

Add a pull-down refresh, which is also available in Flatlist, which is really nice

const Products = () => { const [refreshing, setRefreshing] = useState(false) var data = []; for (var i = 0; i < 20; I++) {data. Push ({key: I, the title: "goods" + I, desc: "this is the description"}); } _renderImte = (item) => { return ( <View style={styles.product_item}> <Image style={styles.product_img} source={require('./images/product_icon.png')}/> <View> <Text >{item.title}</Text> <Text >{item.desc}</Text> </View> </View> ); }; _seperateLine = () => { return ( <View style={{height: 1, backgroundColor: 'purple'}}></View> ); }; _loadData = () => { setRefreshing(true); SetTimeout (() => {Alert. Alert (" refresh done ", null, null); setRefreshing(false); }, 2000); }; return ( <View style={styles.product_list}> <FlatList style={{flex: 1}} data={data} renderItem={({item}) => this._renderImte(item)} ItemSeparatorComponent={this._seperateLine} refreshing={refreshing} onRefresh={ this._loadData }/> </View> ); }Copy the code

Effect:

This is easy to implement using onRefresh and refreshing

6. Page navigation -ReactNavigation

Page navigation requires a control called ReactNavigation, which is very simple to use:

Step 1: Install the control and its dependencies

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack
Copy the code

Step 2: Define a routing file that can be used to jump. This is equivalent to ARouter in Android. Once declared, you can jump with the right Key

/ / router. Js file const Stack = createNativeStackNavigator (); function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Launch"> <Stack.Screen name="Launch" component={Launcher} options={{headerShown: false}}/> <Stack.Screen name="Main" component={MainApp} options={{headerShown: false}}/> </Stack.Navigator> </NavigationContainer> ); } export default App;Copy the code

The third step, jump method, in the control of ReactNavigation stated, props contains navigation related values, you can print the log view, called props. Navigation. Navigate can jump interface, the same can also be in the second parameter values

props.navigation.navigate('Main', {itemId: 1024, otherParm: 'fffffa'});
Copy the code

Based on the above instructions, you can make an implementation like this: add a launch interface and jump to the main interface after 2s; Click the item in the commodity list to enter the details page, and the implementation code is as follows:

//router.js
const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Launch">
        <Stack.Screen name="Launch" component={Launcher} options={{headerShown: false}}/>
        <Stack.Screen name="Main" component={MainApp} options={{headerShown: false}}/>
        <Stack.Screen name="Detail" component={DetailPage}/>
      </Stack.Navigator>
    </NavigationContainer>
  );
}
export default App;

//luanch.js
export const Launcher = (props) => {
    useEffect(() => {
        setTimeout(() => {
            props.navigation.replace('Main', {itemId: 1024, otherParm: 'fffffa'});
        }, 2000);
        return () => {
            
        }
    }, [])
    return (
        <Image style={{flex: 1, width: Dimensions.get('window').width, height: Dimensions.get('window').height}} source={require('./images/product_icon.png')}/>
    );
}

//main.js
  _renderImte = (item) => {
    return (
      <TouchableHighlight key={item.key} onPress={() => {
        props.navigation.navigate('Detail', {itemId: 1234, otherParams: item.title})
      }}>
        <View style={styles.product_item}>
          <Image style={styles.product_img} source={require('./images/product_icon.png')}/>
          <View>
            <Text >{item.title}</Text>
            <Text >{item.desc}</Text>
          </View>
        </View>
      </TouchableHighlight>
    );
  };

//detail.js
export function DetailPage({route, navigation}) {
    const name = route.params.otherParams

    return (
        <View>
            <Text>123123123</Text>
            <Text>{name}</Text>
        </View>
    );
}
Copy the code

Here’s what the App looks like so far:

We have used a lot of common function controls, part of which is just a brush over, such as drop-down refresh and so on there are a lot of API can be used, free to check the document, write more familiar with, important or actual combat.

Recently, AS a rookie, I have been assigned to write RN codes in some projects. I will continue to share my gains.