【问题标题】:How to properly use mapDispatchToProps function in sub component?如何在子组件中正确使用 mapDispatchToProps 函数?
【发布时间】:2017-03-01 10:56:18
【问题描述】:

我正在跟随 Youtube 使用 React Native + Redux 制作简单的 Todo 应用程序。

添加 Todo 效果很好。所以我采取了下一步,试图删除待办事项有问题。视频有点旧,所以版本和平台(我的是安卓)是不同的。所以它的方式有点不同......(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

【问题讨论】:

    标签: reactjs react-native redux react-redux


    【解决方案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

    【讨论】:

      【解决方案2】:

      我找到了解决方案...但我不知道它为什么有效。

      1. 把 prop 改成回调函数

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

        ==>

        onPress={ () =&gt; { this.props.onDeleteTodo(this.props.id) } }

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

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

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

      【讨论】:

        【解决方案3】:

        我真的不知道我是否理解了你的代码...... 顺便说一句,如果您从某个地方导入任何函数,我认为您不必使用调度方法,因为 deleteTodo 不是属性方法。 不使用dispatch()再试一次,另外尝试直接调用deleteTodo()方法。

        编辑:在 onPress 事件中写这个 -> onPress={() => deleteTodo(this.props.id)} 一旦触发事件,它应该调用该方法

        如果它有效,请告诉我!

        【讨论】:

        • 但是 Redux 似乎以这种方式引人注目...我认为它想间接使用调度功能...
        • 您添加的代码在同一个文件中?如果是这样,您应该将这两个类放在单独的文件中,只是为了清晰的代码......此外,我会定义一些原型,如下所示: TodoItem.Proptype = { onDeleteTodo = React.Proptype.func, } 有了这个,我'将确保函数存在,然后在 mapDispatchToProps 中定义它...
        猜你喜欢
        • 2018-01-11
        • 2017-11-14
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        • 2021-07-28
        • 1970-01-01
        • 2014-11-03
        • 1970-01-01
        相关资源
        最近更新 更多