Reputation: 7628
I'm making simple Todo Application using React Native + Redux following Youtube.
Adding Todo works well. so I took next step, trying to deleting todo got problem. The Video is little bit old, so the version and platform(Mine is Android) is different. so the way of it little different... (ES5/ES6 etc.)
Anyway... I want to send action to dispatcher using mapDispatchToProps
's function, onDeleteTodo
, but it's not working.
First I tried to connect the component to store, so Added line TodoItem = connect(mapStateToProps, mapDispatchToProps)(TodoItem);
. but the error still left.
Something wrong... but I can't find, How can I fix it?
Thanks in advance... below is my code.
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity
} from 'react-native';
import {connect} from 'react-redux';
import {addTodo, deleteTodo} from '../actions';
class TodoItem extends Component {
render() {
return (
// ***************************************
// Below line (onPress prop) is problem.
// when I trying to save todo,
// Error "undefined is not a function (evaluating 'this.props.onDeleteTodo(this.props.id)')
<TouchableOpacity onPress={this.props.onDeleteTodo(this.props.id)}>
<View style={styles.todoContainer}>
<Text style={styles.todoText}>
{this.props.text}
</Text>
</View>
</TouchableOpacity>
)
}
}
TodoItem = connect(
mapStateToProps,
mapDispatchToProps
)(TodoItem);
class Main extends Component {
constructor(props) {
super(props);
this.state = {
newTodoText: ""
}
}
render() {
var renderTodos = () => {
return this.props.todos.map((todo) => {
return (
<TodoItem text={todo.text} key={todo.id} id={todo.id}/>
)
})
};
return (
<View style={styles.wrapper}>
<View style={styles.topBar}>
<Text style={styles.title}>
To-Do List
</Text>
</View>
<View style={styles.inputWrapper}>
<TextInput
onChange={(event) => {
this.setState({
newTodoText: event.nativeEvent.text
});
}}
value={this.state.newTodoText}
returnKeyType="done"
placeholder="New Todo"
onSubmitEditing={
() => {
if(this.state.newTodoText && this.state.newTodoText != ''){
this.props.onAddTodo(this.state.newTodoText);
this.setState({
newTodoText: ''
});
}
}
}
underlineColorAndroid='transparent'
style={styles.input}/>
</View>
<ScrollView
automaticallyAdjustContentInsets={false}>
{renderTodos()}
</ScrollView>
</View>
);
}
}
const mapStateToProps = (state) => {
return {
todos: state.todos
}
};
const mapDispatchToProps = (dispatch) => {
return {
onAddTodo: (todo) => {
dispatch(addTodo(todo))
},
onDeleteTodo: (id) => {
dispatch(deleteTodo(id))
}
}
};
Main = connect(
mapStateToProps,
mapDispatchToProps
)(Main);
export default Main
Upvotes: 3
Views: 1689
Reputation: 6507
If you write yoru code like this onPress={ this.props.onDeleteTodo(this.props.id) }
then you are passing to the onPress
property anything that is returned by the function this.props.onDeleteTodo
. In other words, this.props.onDeleteTodo
is executed when the component is rendering.
If you want to pass this function (and not it's returned value) then you need to write onPress={ this.props.onDeleteTodo.bind(this, this.props.id) }
. This way you are passing this function with this
as a context and this.props.id
as it's first argument. More about this method here: Use of the JavaScript 'bind' method
Upvotes: 1
Reputation: 31
I don't really know If I've understood your code... By the way, if you are importing any function from somewhere, I think that you don't have to use dispatch method, since deleteTodo is not a property method. Try again without dispatch(), moreover, try to call directly deleteTodo() method.
EDIT: in onPress event write this -> onPress={() => deleteTodo(this.props.id)} It should call the method onces the event is triggered
And let me know if it works!
Upvotes: 0
Reputation: 7628
I found the solution... but I don't know why it works.
change prop to callback function
onPress={this.props.onDeleteTodo(this.props.id)}
==>
onPress={ () => { this.props.onDeleteTodo(this.props.id) } }
: Is onPress prop only receive callback function? I don't know.
const mapStateToProps and mapDispatchToProps
: Is const ...
variable only can reference below its declaration? I don't know also.
Upvotes: 0