I'm trying to create a simple to-do application to practice React-Native and I'm having trouble retrieving the items when the componentDidMount
The app state
:
this.state = {
task: "",
tasks: []
};
When the user adds a new task handleAddTask
runs and I attached the AsyncStorage.setItem
as a callback for setState
so that the tasks array is saved to the storage after the state is updated.
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));
}
);
}
};
Similarly, when the user taps on a list item handleDelete
runs, it removes the selected task from the tasks array and updates the AsyncStorage
handleDelete = index => {
this.setState(
prevState => {
return {
tasks: prevState.tasks.filter((place, i) => {
return i !== index;
})
};
},() => {
AsyncStorage.setItem("tasks", JSON.stringify(this.state.tasks));
}
);
};
However, I'm trying to retreive the tasks array from AsyncStorage
inside componentDidMount
like so :
componentDidMount() {
AsyncStorage.getItem("tasks")
.then(value => {
this.setState({ "tasks": value });
})
.done();
}
The way I'm displaying the tasks list is by passing the state through a component called List
:
<List
listItems={this.state.tasks}
handleDelete={this.handleDelete}
/>
Inside List.js
I'm mapping through the tasks array:
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>
);
}
}
And I get the following error:
TypeError: undefined is not a function (evaluating 'this.props.listItem.map')
I've been commenting lines here and there to see where the problems is and I can only assume that it's in the way I'm getting the items in componentDidMount
Is there something about asynchronous JavaScript that I missed?
Also, do I have to JSON.parse
when I do getItem
?
If anyone has additional feedback about my code in general I'd love to learn more.
Thanks in advance!
You saved to storage JSON.stringify()
values, then used it without using JSON.parse()
. I think that this is the problem. You can check it by stop on break point on your List
component render before it maps its props, and detect that your props.listItems
isn't array after componentDidMount
.