Часть IV

Итак, теперь, когда я рассказал о том, что было связано с настройкой серверной части, я хочу немного больше поговорить о внешнем интерфейсе, о том, как я занимался получением местоположений и о том, как различные компоненты в приложении разговаривать друг с другом и делиться информацией о местоположении друг с другом.

Это не совсем ясно, но Xcode требует от вас некоторой настройки, чтобы включить определенные функции в вашем приложении. Возьмем, к примеру, «фоновые режимы». Для моего приложения мне нужно, чтобы ваш iPhone мог отслеживать ваше местоположение, и хотя у меня есть javascript:

getLocation = () => {    
    navigator.geolocation.getCurrentPosition(currentPosition => {
         this.props.dispatchedNewCenter({latitude:     
              currentPosition.coords.latitude,  
              longitude:currentPosition.coords.longitude}),                          
         this.props.dispatchedCircleCenter({latitude: 
              currentPosition.coords.latitude, 
              longitude:currentPosition.coords.longitude})                          
     })                      
}

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

Фоновые режимы находятся на вкладке возможностей в вашем проекте Xcode, и там вам нужно будет проверять обновления местоположения. Это также будет верно, если вы собираетесь использовать покупки в приложении, которые не находятся в фоновых режимах, но, тем не менее, это возможность отметить «возможности».

Я хочу воспользоваться моментом, чтобы отметить несколько вещей о приведенном выше коде; это довольно стандартный способ (насколько я могу судить) геолокации вашего пользователя, но:
а) это функция, которая вызывается и не «следит» за вашим местоположением
б) есть что-то происходит с props.dispatchedCircleCenter() и т. д.

У HustleTime действительно есть 2 ключа в Redux, которые содержат информацию о местоположении. Есть центр круга, то есть место, которое находится в центре просматриваемой карты, и второе место, где на самом деле стоит пользователь. И это заставляет задать, может быть, 2 вопроса:
а) почему мы не отслеживаем местоположение при перемещении пользователя?
б) что такое Redux и каковы ключи в Redux?

Простой ответ на первый вопрос: да, мы отслеживаем местоположение пользователя. Но эта функция вызывается в другом месте просто потому, что приложению действительно все равно, где вы стоите, если вы сначала не откроете приложение или не переместите карту на свое местоположение. Чтобы отслеживать местоположение пользователя, я установил следующее в компоненте, который отображает маленькую иконку пользователя на карте, и это выглядит примерно так:

getUserLocation = () => {                         
    navigator.geolocation.getCurrentPosition(userPosition => {                          
        this.setState({
            lat: userPosition.coords.latitude
            lng: userPosition.coords.longitude                          
        })
     })     
}                                                
componentDidMount(){                     
    this.getUserLocation()                        
}                                                
componentDidUpdate(){                     
    this.watchID = navigator.geolocation.watchPosition(                               
        position => {                    
            this.setState({                 
                lat:position.coords.latitude,                 
                lng:position.coords.longitude                        
        })                           
    })                    
}

Для целей определения местоположения пользователя мы просто используем состояние, а не Redux (подробнее об этом чуть позже) просто потому, что нам действительно нужно отслеживать данные о местоположении только для рендеринга маленькой иконки на карте, и для этого мы повторное использование метода жизненного цикла componentDidUpdate(), доступного в React Native.

Вы можете сделать это с помощью Redux, который позволяет управлять состоянием нескольких компонентов. Вот чем props.dispatchedCircleCenter был раньше. По сути, мы берем эту функцию из redux и сопоставляем ее с реквизитами, чтобы она была доступна в каждом компоненте, который мы хотим, чтобы она была доступна здесь. Вот пример того, как это выглядит в компоненте:

const mapStateToProps = (state) => {                    
    return {                 
        stations: state.stations,                 
        circleCenter: state.circleCenter                    
    }                       
}
const mapDispatchToProps = (dispatch) => {                     
    return {                  
        dispatchedFetchStations: (stations) => dispatch(fetchStations(stations)),                          
        dispatchedCircleCenter: (coords) => dispatch(setCircleCenter(coords)),                          
        dispatchedNewCenter: (coords) => dispatch(setNewCenter(coords)),                          
        dispatchedActiveMarker: (name) => dispatch(setActiveMarker(name))                     
    }                       
}

Здесь мы сопоставляем 2 ключа с состоянием и 4 функции с реквизитами. Теперь каждый из них будет доступен в этом конкретном компоненте в качестве реквизита.

Redux — особенно полезная библиотека, которую можно включить практически в любой проект React-Native, но она не ограничивается только React-Native. Он доступен для многих, многих фреймворков js. Я настоятельно рекомендую привыкнуть к работе с Redux, даже если это означает использование его в приложении, которому на самом деле не нужно передавать свойства от компонента к компоненту.

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