我在Youtube之后使用React Native + Redux制作简单的Todo应用程序。
添加Todo效果很好。所以我采取了下一步,试图删除todo问题。视频有点旧,所以版本和平台(我的是Android)是不同的。所以它的方式有点不同......(ES5 / ES6等)
无论如何......我想使用mapDispatchToProps
的函数onDeleteTodo
向调度员发送操作,但它不起作用。
首先我尝试将组件连接到存储,因此添加了行TodoItem = connect(mapStateToProps, mapDispatchToProps)(TodoItem);
。但错误仍然存在。
出了点问题......但我找不到,我该如何解决?
提前致谢...以下是我的代码。
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
答案 0 :(得分:1)
如果你像这样onPress={ this.props.onDeleteTodo(this.props.id) }
编写yoru代码,那么你将onPress
属性传递给函数this.props.onDeleteTodo
返回的任何内容。换句话说,在组件呈现时执行this.props.onDeleteTodo
。
如果你想传递这个功能(而不是它的返回值)那么你需要写onPress={ this.props.onDeleteTodo.bind(this, this.props.id) }
。这样,您将this
作为上下文传递此函数,并将this.props.id
作为其第一个参数。有关此方法的更多信息,请访问:Use of the JavaScript 'bind' method
答案 1 :(得分:0)
我真的不知道如果我了解你的代码...... 顺便说一句,如果你从某个地方导入任何函数,我认为你不必使用调度方法,因为deleteTodo不是属性方法。 再试一次不带dispatch(),而且,尝试直接调用deleteTodo()方法。
编辑:在onPress事件中写这个 - &gt; onPress = {()=&gt; deleteTodo(this.props.id)} 它应该调用方法onces事件被触发
让我知道它是否有效!
答案 2 :(得分:0)
我找到了解决方案......但我不知道它为什么会起作用。
将道具改为回调函数
onPress={this.props.onDeleteTodo(this.props.id)}
==&GT;
onPress={ () => { this.props.onDeleteTodo(this.props.id) } }
:onPress prop是否只接收回调函数?我不知道。
const mapStateToProps and mapDispatchToProps
:const ...
变量只能在其声明下方引用吗?我也不知道。