componentDidMount

时间:2018-01-26 05:19:56

标签: javascript reactjs react-native asyncstorage

我正在尝试创建一个简单的待办事项来练习React-Native,而我在componentDidMount

时检索项目时遇到了问题

应用state

this.state = {
  task: "",
  tasks: []
};

当用户添加新任务handleAddTask时,我将AsyncStorage.setItem附加为setState的回调,以便在状态更新后将tasks数组保存到存储中。

handleAddTask = () => {

  let notEmpty = this.state.task.trim().length > 0;
  if (notEmpty) {
    this.setState(
      prevState => {
        return {
          tasks: prevState.tasks.concat(prevState.task)
        };
      },() => {
        AsyncStorage.setItem("tasks", JSON.stringify(this.state.tasks));
      }
    );
  }

};

同样,当用户点击列表项handleDelete时,它会从任务数组中删除所选任务并更新AsyncStorage

handleDelete = index => {

  this.setState(
    prevState => {
      return {
        tasks: prevState.tasks.filter((place, i) => {
          return i !== index;
        })
      };
    },() => {
      AsyncStorage.setItem("tasks", JSON.stringify(this.state.tasks));
    }
  );

};

但是,我正试图从AsyncStorage componentDidMount内部检索任务数组,如下所示:

componentDidMount() {
  AsyncStorage.getItem("tasks")
    .then(value => {
      this.setState({ "tasks": value });
    })
    .done();
}

我显示任务列表的方式是将状态传递给名为List的组件:

<List
  listItems={this.state.tasks}
  handleDelete={this.handleDelete}
/>

List.js内部我正在通过任务数组进行映射:

export default class List extends Component {

  render() {

    const namesOutput = this.props.listItems.map((name, i) => (
      <TouchableOpacity
        key={i}
        onPress={() => this.props.handleDelete(i)}
        activeOpacity={0.6}
        style={styles.listItemContainer}
      >
        <Text style={styles.listItemText}>{name}</Text>
      </TouchableOpacity>
    ));

    return (
      <View style={styles.listContainer}>
        <ScrollView>{namesOutput}</ScrollView>
      </View>
    );
  }

}

我收到以下错误:

TypeError:undefined不是函数(评估'this.props.listItem.map')

我一直在这里和那里评论线条,看看问题出在哪里,我只能假设这是我在componentDidMount

中获取项目的方式

我错过了异步JavaScript吗? 另外,当我JSON.parse时,我是否需要getItem? 如果有人对我的代码有额外的反馈,我很乐意了解更多。

提前致谢!

2 个答案:

答案 0 :(得分:1)

您保存到存储JSON.stringify()值,然后在不使用JSON.parse()的情况下使用它。我认为这是问题所在。您可以在List组件渲染上的断点处停止检查,然后再映射其道具,并在props.listItems之后检测到您的componentDidMount不是数组。

答案 1 :(得分:0)

AsyncStorage返回一个承诺。因此,当您调用componentDidMount中的项目时,代码将在检索到值之前通过.then

我的建议是你给listItem一些虚拟对象,这样它在调用它时就不会被定义。

第二个建议是使用await而不是.then并在调用listenItem.map时使用辅助函数,以便在加载值之前不会调用它。