【问题标题】:React-Native based APK crashes on my phone基于 React-Native 的 APK 在我的手机上崩溃
【发布时间】:2017-06-14 08:52:53
【问题描述】:

所以我参加了关于 Udemy 的基本 react-native 课程(讲师没有回应)。第一个任务是制作一个“待办事项”列表,这是我制作的。遵循此页面上的所有说明: https://facebook.github.io/react-native/docs/signed-apk-android.html 构建成功,我的应用程序在安装后启动,但是当我按下输入字段时,它就崩溃了。知道有什么问题吗? 这是我的代码,即使我很确定问题出在其他地方:

    import React, {Component} from 'react';
import {
    StyleSheet,
    Text,
    TextInput,
    View,
    TouchableOpacity,
    ScrollView,
    AsyncStorage
} from 'react-native';

const Main = React.createClass({
  getInitialState () {
return ({
tasks: [],
completedTasks:[],
task:''
})
  },

componentWillMount() {
AsyncStorage.getItem('tasks')
.then((response) => {
  this.setState ({tasks: JSON.parse(response)})
});
AsyncStorage.getItem('completedTasks')
.then((response) => {
  this.setState({completedTasks: JSON.parse(response)})
});
  },

componentDidUpdate() {
  this.setStorage();
},  

setStorage() {
    AsyncStorage.setItem('tasks', JSON.stringify(this.state.tasks));
    AsyncStorage.setItem('completedTasks', JSON.stringify(this.state.completedTasks));

  },

  renderList(tasks){
return(
  tasks.map((task, index) =>{
    return(
    <View key={task} style={styles.task}>
      <Text>
      {task}
        </Text>
        <TouchableOpacity
        onPress={()=>this.completeTask(index)}
        >
        <Text>
          &#10003;
          </Text>
          </TouchableOpacity>
        </View>
    )
  })
)
  },
  renderCompleted(tasks) {
return (
  tasks.map((task, index) => {
    return(
      <View key={task} style={styles.task}>
        <Text style={styles.completed}>
          {task} 
          </Text>
          <TouchableOpacity
          onPress={()=>this.deleteTask(index)}
          >
            <Text>
              &#10005;
              </Text>
            </TouchableOpacity>
          </View>
    )
  })
)
  },

deleteTask(index){
  let completedTasks = this.state.completedTasks;
  completedTasks = completedTasks.slice(0, index).concat(completedTasks.slice(index+1));
  this.setState({completedTasks});
},

completeTask(index) {
let tasks = this.state.tasks;
tasks = tasks.slice(0, index).concat(tasks.slice(index+1));

let completedTasks = this.state.completedTasks;
completedTasks = completedTasks.concat([this.state.tasks[index]]);

this.setState({
  tasks,
  completedTasks
});


  },
  addTask() {
   let tasks = this.state.tasks.concat([this.state.task]);
   this.setState({tasks})

  },
  render() {
    return (
   <View style={styles.container}>
        <Text style={styles.header}>
        Muli's To-Do
             </Text>
            <TextInput underlineColorAndroid={'transparent'}
            style={styles.input}
            onChangeText={(text) => {
              this.setState({task: text});
            } }
            onEndEditing={()=> this.addTask()}
            />
            <ScrollView>
{this.renderList(this.state.tasks)}
            {this.renderCompleted(this.state.completedTasks)}
              </ScrollView>

            </View>
    )
  }
})

const styles = StyleSheet.create({
container: {
  flex:1,
  backgroundColor: '#3b5998'

},
header: {
color:'white',
margin: 0,
marginTop:10,
textAlign: 'center',
fontSize: 18

},
task: {
  elevation:5,
  backgroundColor:'white',
  flexDirection: 'row',
  height: 60,
  borderWidth:1,
  borderColor: 'black',
  justifyContent:'space-between',
  alignItems:'center',
  padding: 20,
  margin: 2,
  borderRadius: 5,
},
input: {
  elevation:10,
  backgroundColor:'white',
  height: 60,
  borderWidth:1,
  borderBottomWidth: 1,
  borderRadius: 5,
  borderColor:'black',
  textAlign: 'center',
  margin:10,
  marginBottom:30,
  fontSize:15,
  color: '#3b5998',
},
completed: {
  color: '#555',
  textDecorationLine: 'line-through'
}
})

module.exports = Main;

请让我知道我可以提供的其他相关信息。

谢谢!!

【问题讨论】:

标签: android-studio react-native react-native-android


【解决方案1】:

似乎在componentWillMount 期间,您为taskscompletedTasks 设置了未定义的状态。在全新设置中,您的存储空间将是空的,并且任务和已完成任务的响应都将是未定义的。

您可以通过快速检查是否存在响应来调整 componentWillMount,如下所示:

componentWillMount() {
    AsyncStorage.getItem('tasks')
      .then((response) => {
        if (response) {
          this.setState({tasks: JSON.parse(response)})
        }
      });
    AsyncStorage.getItem('completedTasks')
      .then((response) => {
        if (response) {
          this.setState({completedTasks: JSON.parse(response)})
        }
      });
  },

【讨论】:

  • 谢谢,我明白你的意思了!但这可能是应用程序在我的设备上崩溃的原因吗?
  • 是的,原因是,一旦你开始输入,状态就会更新并且组件会尝试重新渲染。在重新渲染时,会调用 renderList(tasks) 方法,然后运行以下代码 tasks.map((task, index) =&gt; {。这将引发错误,因为您试图在空对象上调用 map 函数。
  • 好的,有道理。所以我会用你的修复编辑它并回发。谢谢!
  • 当然可以,希望对您有所帮助。
  • 可以,非常感谢!顺便说一句,知道每次设置“待办事项”时如何重置(清空)输入字段吗?
猜你喜欢
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 2018-05-16
  • 2020-01-18
  • 2023-03-18
  • 2021-12-29
  • 2023-02-08
  • 1970-01-01
相关资源
最近更新 更多