如何在子组件中正确使用 mapDispatchToProps 函数?
How to properly use mapDispatchToProps function in sub component?
我正在按照 Youtube 使用 React Native + Redux 制作简单的 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
我真的不知道我是否理解了您的代码...
顺便说一下,如果你从某个地方导入任何函数,我认为你不必使用 dispatch 方法,因为 deleteTodo 不是 属性 方法。
不用dispatch()再试,而且直接调用deleteTodo()方法试试
编辑:在 onPress 事件中写这个 -> onPress={() => deleteTodo(this.props.id)}
一旦事件被触发,它应该调用该方法
如果有效,请告诉我!
我找到了解决方案...但我不知道它为什么有效。
将 prop 更改为回调函数
onPress={this.props.onDeleteTodo(this.props.id)}
==>
onPress={ () => { this.props.onDeleteTodo(this.props.id) } }
: onPress prop 只能接收回调函数吗?我不知道。
- 将连接语句移动到
const mapStateToProps and mapDispatchToProps
下面
: const ...
变量只能在它的声明下面引用吗?我也不知道。
如果您编写这样的代码 onPress={ this.props.onDeleteTodo(this.props.id) }
那么您将传递给 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
我正在按照 Youtube 使用 React Native + Redux 制作简单的 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
我真的不知道我是否理解了您的代码... 顺便说一下,如果你从某个地方导入任何函数,我认为你不必使用 dispatch 方法,因为 deleteTodo 不是 属性 方法。 不用dispatch()再试,而且直接调用deleteTodo()方法试试
编辑:在 onPress 事件中写这个 -> onPress={() => deleteTodo(this.props.id)} 一旦事件被触发,它应该调用该方法
如果有效,请告诉我!
我找到了解决方案...但我不知道它为什么有效。
将 prop 更改为回调函数
onPress={this.props.onDeleteTodo(this.props.id)}
==>
onPress={ () => { this.props.onDeleteTodo(this.props.id) } }
: onPress prop 只能接收回调函数吗?我不知道。
- 将连接语句移动到
const mapStateToProps and mapDispatchToProps
下面
: const ...
变量只能在它的声明下面引用吗?我也不知道。
如果您编写这样的代码 onPress={ this.props.onDeleteTodo(this.props.id) }
那么您将传递给 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