Это серия статей, состоящая из двух частей. Вторая часть этой серии, посвященная сервисам AWS и Backend, готовится.

React Native - AWS Lambda - Dynamodb - S3

Всем привет,

В этой статье я представлю мобильное приложение, которое я сделал в прошлом. Я думаю о том, чтобы продвинуться вперед, продемонстрировав немного теории и код. Надеюсь, это будет кому-то полезно.

В этой статье я не буду учить React Native или AWS Lambda. Люди, которым это нужно, могут посмотреть разные ресурсы.

Опять же, в этой статье я не буду объяснять детали по очереди. Такое подробное объяснение означает длинную серию. К сожалению, сейчас у меня не так много времени, но, надеюсь, в будущем.

Я пишу эту статью для тех, кто знает React Native и AWS хотя бы на начальном уровне. Достаточно только знания AWS. Не нужно знать Lambda. В этой статье я покажу больше кодов. Повествования не будет :(

Пожалуйста, поделитесь своими вопросами и предложениями. Хорошее чтение

Приложение

Это приложение разработано как решение для сферы образования. Я разработал мобильное приложение, в котором студенты, готовящиеся к экзаменам, могут задавать вопросы. После того, как ученик задает вопрос, на телефон соответствующего учителя отправляется уведомление в соответствии с выбранным типом урока. Затем учитель решает вопрос и загружает его в приложение. Учащийся получает уведомление о решении.

Почему я использовал в приложении React Native?

В последние годы React Native начал делать себе имя среди библиотек, используемых для разработки мобильных приложений. Написание с использованием JS, компиляция общего кода для Android и IOS и простота - вот основные моменты для меня. Если вам нравится JS или TS, React Native для вас.

Выбранный мной шаблон React Native: Теперь шаблон UI React Native

Дизайн важен при разработке мобильных приложений. Мы, разработчики, не являемся дизайнерами, и я считаю, что лучше всего доверить эту работу специалистам. По этой причине я нашел и использовал прикрепленный шаблон среди бесплатных нативных шаблонов реагирования, которые искал в Интернете. Он очень надежный, понятный, расширяемый и простой в освоении. Я очень рекомендую это.



Репозиторий кода проекта

Вы можете найти и скачать коды проекта здесь. Взносы также приветствуются.

React Native Структура папок и важные файлы

Файловой структуры, которая появляется при создании пустого проекта React Native, вполне достаточно для общих проектов. Два важных файла в проекте React native - это файлы package.json, package-lock.json. Это файлы, содержащие список и версии js-библиотек, которые вы будете использовать в своем проекте, поддерживающем реакцию. Одна нота; Перед запуском проекта React Native вам необходимо установить менеджер пакетов. Я использую в своем проекте Диспетчер пакетов узлов.

Вы можете найти все коды, связанные с React-Native, в папке bulutasor / BulutaSorFrontend2. Вот папки, которые следует изучить:

экраны: все коды экранов находятся в этой папке.

Пример кода экранов:

/* eslint-disable no-console */
import React from 'react';
import {
  StyleSheet, Dimensions, ScrollView, Alert
} from 'react-native';// cache app images

// import * as Notifications from 'expo-notifications';
import { connect } from 'react-redux';
import {
  Block, Text, theme, withGalio
} from 'galio-framework';
import AnimatedLoader from 'react-native-animated-loader';
import { Card } from '../components';

const { width } = Dimensions.get('screen');

class StudentsSolvedQuestionListScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: false,
      error: null,
    };
  }

  componentDidMount() {
    this.state.visible = false;
    this.state.error = null;
  }

  renderArticles = () => {
    const { error } = this.state;
    const { questions } = this.props;
    return (

      <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.articles}>
        <Block flex>
          {error ? <p>{error.message}</p> : null}
          {
            (Array.isArray(questions))
              ? questions.filter((item) => item.state === 'passive').map(
                (question) => <Card item={question} key={question.s3Key} cevapGoster="true" horizontal />
              )
              : (
                <Text>
                  Henüz çözülmüş bir sorun yok.
                </Text>
              )
          }
        </Block>
      </ScrollView>
    );
  };

  render() {
    const { visible } = this.state;
    return (
      <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.articles}>
        <Block flex style={styles.home}>
          <Block center style={{ flex: 30 }}>
            <AnimatedLoader
              visible={visible}
              overlayColor="rgba(255,255,255,0.75)"
              source={require('./spinner.json')}
              animationStyle={styles.lottie}
              speed={1}
            />
            {this.renderArticles()}
          </Block>
        </Block>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  home: {
    width,
  },
  articles: {
    width: width - theme.SIZES.BASE * 2,
    paddingVertical: theme.SIZES.BASE,
    paddingHorizontal: 2,
    fontFamily: 'montserrat-regular',
  },
});

function mapStateToProps(storeState) {
  return {
    userName: storeState.userName,
    password: storeState.password,
    questions: storeState.questions
  };
}

function mapDispatchToProps() {
  return {
    // setQuestions()
  };
}
export default withGalio(connect(mapStateToProps, mapDispatchToProps)(StudentsSolvedQuestionListScreen));

компоненты: в этой папке вы можете найти библиотеку компонентов, которая поставляется с шаблоном React Native.

import React, { useState } from 'react';
import {
  Alert,
  Modal,
  StyleSheet,
  TouchableWithoutFeedback,
  Keyboard,
  View,
  Dimensions,
  TouchableOpacity,
} from 'react-native';
import {
  Text, theme, Block
} from 'galio-framework';
import { useNavigation } from '@react-navigation/native';
import { useSelector } from 'react-redux';
import ArButton from './Button';
import Icon from './Icon';
import nowTheme from '../constants/Theme';

const DismissKeyboard = ({ children }) => (
  <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>{children}</TouchableWithoutFeedback>
);

const { width, height } = Dimensions.get('screen');

const SessionBar = (props) => {
  const [modalVisible, setModalVisible] = useState(0);
  const user = useSelector((state) => state.user);
  const navigation = useNavigation();
  let userType = 'Öğrenci';
  const { isTeacher } = user;
  if (isTeacher) {
    userType = 'Öğretmen';
  }
  console.log(`isTeacher:${isTeacher}`);
  console.log(`userType:${userType}`);
  return (
    <Block>
      <Modal
        animationType="slide"
        visible={modalVisible}
        style={styles.modalView}
        transparent
        onRequestClose={() => {
          Alert.alert('Modal has been closed.');
        }}
      >
        <View
          style={{
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            margin: 80,
            padding: 80,
            borderColor: nowTheme.COLORS.BLACK,
            borderRadius: 10,
            backgroundColor: nowTheme.COLORS.WHITE,
          }}
        >
          <ArButton
            color="info"
            round
            style={styles.createButton}
            onPress={() => { setModalVisible(false); }}
            title="Kapat"
          >
            <Text
              style={{ fontFamily: 'montserrat-bold' }}
              size={14}
              color={nowTheme.COLORS.WHITE}
            >
              Kapat
            </Text>
          </ArButton>
          <Block>
            <Text
              size={16}
              muted
              style={{
                width: '100%',
                color: '#2c2c2c',
                fontWeight: 'bold',
                lineHeight: 20,
                fontSize: 19,
                fontFamily: 'montserrat-bold',
                margin: 10,
                zIndex: 2,
                textAlign: 'center',
              }}
            >
              {userType}
            </Text>
            <Text
              size={16}
              muted
              style={{
                width: '100%',
                color: '#2c2c2c',
                fontWeight: 'bold',
                lineHeight: 20,
                fontSize: 19,
                fontFamily: 'montserrat-bold',
                margin: 10,
                zIndex: 2,
                textAlign: 'center',
              }}
            >
              {user.userName}
            </Text>
          </Block>
          <ArButton
            color="primary"
            round
            style={styles.createButton}
            onPress={() => { setModalVisible(false); logout(); navigation.navigate('LoginScreen'); }}
            title="Oturumu Kapat"
          >
            <Text
              style={{ fontFamily: 'montserrat-bold' }}
              size={14}
              color={nowTheme.COLORS.WHITE}
            >
              Oturumu Kapat
            </Text>
          </ArButton>
        </View>
      </Modal>
      <Block flex row right>
        <TouchableOpacity
          style={[styles.profileButton]}
          onPress={() => {
            setModalVisible(true);
          }}
        >
          <Text>{user.userName}</Text>
          <Icon
            family="NowExtra"
            size={16}
            name="basket2x"
            color={nowTheme.COLORS.WHITE}
          />

        </TouchableOpacity>
      </Block>
    </Block>
  );
};
export default SessionBar;

const styles = StyleSheet.create({
  registerContainer: {
    marginTop: 55,
    width: width * 0.9,
    height: height < 812 ? height * 0.8 : height * 0.8,
    backgroundColor: nowTheme.COLORS.WHITE,
    borderRadius: 4,
    shadowColor: nowTheme.COLORS.BLACK,
    shadowOffset: {
      width: 0,
      height: 4,
    },
    shadowRadius: 8,
    shadowOpacity: 0.1,
    elevation: 1,
    overflow: 'hidden',
  },

  centeredView: {
    flex: 1,
    justifyContent: 'flex-start',
    alignItems: 'center',
    margin: 20,
    backgroundColor: nowTheme.COLORS.WHITE,
    padding: 20,
  },
  modalView: {
    backgroundColor: theme.COLORS.WHITE,
    borderRadius: 20,
    margin: 35,
    padding: 35,
    height: height * 0.6,
    width: width * 0.6,
    justifyContent: 'flex-start',
    alignItems: 'stretch',
    borderColor: theme.COLORS.BLACK,

  },
  openButton: {
    backgroundColor: theme.COLORS.WHITE,
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
  title: {
    flex: 2,
    height: height * 0.07,
    alignItems: 'center',
    justifyContent: 'center',
  },
  titleTextStyle: {
    fontWeight: '400',
    fontSize: theme.SIZES.FONT * 2,
    color: theme.COLORS.BLACK,
    paddingTop: 20
  },

  createButton: {
    width: width * 0.5,
    marginTop: 25,
    marginBottom: 40,
  },

  profileButton: {
    padding: 12,
    position: 'relative',
    width: width * 0.2,
  },

  cikisButton: {
    padding: 12,
    position: 'relative',
    width: width * 0.2,
  }
});

Android и IOS: в этих папках вы можете найти конфигурации, зависящие от среды, созданные из кодов, поддерживающих реакцию, во время компиляции. Для использования некоторых сторонних библиотек требуются настройки, специфичные для операционной системы. В этом случае коды, в которые мы будем вмешиваться, находятся здесь. В нормальных условиях мы не занимаемся разработкой в ​​этих папках.

Appium: когда мы разрабатываем мобильное приложение, нам нужно протестировать его на разных устройствах. Потому что в целом наше приложение может работать по-разному в зависимости от модели и версии операционной системы, памяти и размера экрана или, что еще хуже, может не работать. :( Может быть очень полезно протестировать наше приложение на ферме устройств, чтобы выявить эту ситуацию до того, как конечные пользователи испытают ее в нашем приложении. Я определенно рекомендую это. Вы можете найти AWS Device Farm здесь.

Redux

Redux - это хранилище данных. Обычно рекомендуется разделять данные экранами приложений. Таким образом обеспечивается согласованность данных между экранами или между различными компонентами на одном экране. Redux теперь является обязательным компонентом в библиотеках JS, таких как React Native, Vue или Angular. Вы можете получить доступ к деталям по адресам ниже.





И одна турецкая статья из Зафер Аян.



Заключение

В этой статье я попытался представить код реагирования моего мобильного приложения, возможно, это кого-то вдохновит. Во второй статье этой серии я расскажу о Backend.

Желаю всем прекрасной жизни