如何在子组件中正确使用mapDispatchToProps函数?

时间:2017-03-01 10:56:19

标签: reactjs react-native redux react-redux

我在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

3 个答案:

答案 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)

我找到了解决方案......但我不知道它为什么会起作用。

  1. 将道具改为回调函数

    onPress={this.props.onDeleteTodo(this.props.id)}

    ==&GT;

    onPress={ () => { this.props.onDeleteTodo(this.props.id) } }

  2. :onPress prop是否只接收回调函数?我不知道。

    1. 将连接语句移至const mapStateToProps and mapDispatchToProps
    2. 的下方

      const ...变量只能在其声明下方引用吗?我也不知道。