Я читаю эту книгу, издавая Мэннинга, «Реагируй на родной в действии», в учебнике в главе 6. Я пытаюсь создать приложение, которое можно использовать для добавления и отображения города, но, пытаясь добавить город, я получаю эта ошибка
typeerror: null не является объектом (оценивающим towns.pu sh)
, указывающим на
App. js строка 42, столбец 11
и
AddCity. js строка 30, столбец 35
. И я действительно не знаю, что делать, чтобы решить проблему.
На самом деле, я следую учебному пособию реагировать в действии Дабита Нейдера
Это
Приложение. js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
AsyncStorage
} from 'react-native';
import Tabs from './src'
const key = 'state'
const initialState = [{
city: 'Paris',
country: 'France',
id: 0,
locations: []
},
{
city: 'Tokyo',
country: 'Japan',
id: 1,
locations: []
}]
export default class App extends Component {
state = {
cities: []
}
async componentDidMount() {
try {
let cities = await AsyncStorage.getItem(key)
cities = JSON.parse(cities)
this.setState({ cities })
} catch (e) {
console.log('error from AsyncStorage: ', e)
}
}
addCity = (city) => {
const cities = this.state.cities
cities.push(city)
this.setState({ cities })
AsyncStorage.setItem(key, JSON.stringify(cities))
.then(() => console.log('storage updated!'))
.catch(e => console.log('e: ', e))
}
addLocation = (location, city) => {
const index = this.state.cities.findIndex(item => {
return item.id === city.id
})
const chosenCity = this.state.cities[index]
chosenCity.locations.push(location)
const cities = [
...this.state.cities.slice(0, index),
chosenCity,
...this.state.cities.slice(index + 1)
]
this.setState({
cities
}, () => {
AsyncStorage.setItem(key, JSON.stringify(cities))
.then(() => console.log('storage updated!'))
.catch(e => console.log('e: ', e))
})
}
render() {
return (
<Tabs
screenProps={{
cities: this.state.cities,
addCity: this.addCity,
addLocation: this.addLocation
}}
/>
)
}
}
Это
AddCity. js
import React from 'react'
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity
} from 'react-native'
import uuidV4 from 'uuid/v4'
import { colors } from '../theme'
class AddCity extends React.Component {
state = {
city: '',
country: ''
}
onChangeText = (key, value) => {
this.setState({ [key]: value })
}
submit = () => {
if (this.state.city === '' || this.state.country === '') alert('please complete form')
const city = {
city: this.state.city,
country: this.state.country,
id: uuidV4(),
locations: []
}
this.props.screenProps.addCity(city)
this.setState({
city: '',
country: ''
}, () => {
this.props.navigation.navigate('Cities')
})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.heading}>Cities</Text>
<TextInput
placeholder='City name'
onChangeText={val => this.onChangeText('city', val)}
style={styles.input}
value={this.state.city}
/>
<TextInput
placeholder='Country name'
onChangeText={val => this.onChangeText('country', val)}
style={styles.input}
value={this.state.country}
/>
<TouchableOpacity onPress={this.submit}>
<View style={styles.button}>
<Text style={styles.buttonText}>Add City</Text>
</View>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
button: {
height: 50,
backgroundColor: '#666',
justifyContent: 'center',
alignItems: 'center',
margin: 10
},
buttonText: {
color: 'white',
fontSize: 18
},
heading: {
color: 'white',
fontSize: 40,
marginBottom: 10,
alignSelf: 'center'
},
container: {
backgroundColor: colors.primary,
flex: 1,
justifyContent: 'center'
},
input: {
margin: 10,
backgroundColor: 'white',
paddingHorizontal: 8,
height: 50
}
})
export default AddCity
реагировать -навигатор используется версия 2.0.1