无法连接mapStateToProps和mapDispatchToProps

时间:2019-01-21 04:53:08

标签: react-native react-redux

我收到一个未定义的错误,而不是一个函数(正在评估'this.props.addTodo(text)') 在我引入反应导航之前,我的代码运行良好,因为之后我想从第二个屏幕中添加待办事项,即计数器,并希望查看第一屏幕上的列表是否已更新。但是我坚持在第一个屏幕上添加待办事项,因为它抛出了以上错误。 我是React-native和Redux以及Js的完全入门者。顺便说一句谢谢和提前 这是我的代码:

App.js

    import React from 'react';
    import { StyleSheet, Text, View, AppRegistry } from 'react-native';
    import TodoApp from './src/TodoApp'
    import store from './app/store/index'
    import { Provider } from 'react-redux'
    import {CounterR} from './app/counterR';
    import {Counter} from './app/counter';
    import {createStackNavigator, createAppContainer} from 'react- 
    navigation'

    export default class App extends React.Component {
        render() {
        return (
            <Provider store={store}>
              <AppContainer />
            </Provider>
        );
      }
    }

    const stack  = createStackNavigator({
      Home: CounterR,
      Second: Counter
    },{
      initialRouteName: 'Home' 
     })

    const AppContainer = createAppContainer(stack)
    const styles = StyleSheet.create({
    container: {
       flex: 1,
       backgroundColor: '#fff',
       alignItems: 'center',
       justifyContent: 'center',
      },
     });

CounterR.js

    import React, { Component } from 'react';
    import {View, 
        TouchableOpacity, 
        Text, 
        Dimensions,
        StyleSheet, 
        TextInput,
        FlatList,
        Keyboard} from 'react-native';
    import {connect} from 'react-redux'
    import { addTodo } from './actions/index'
    import { toggleTodo } from './actions/index'
    import {NavigationAction} from 'react-navigation'
    import store from './store/index'
    import { Provider } from 'react-redux'
    const { width, height } = Dimensions.get("window");

    export class CounterR extends Component{

        state = {
            text: ""
        }

        add = text => {
            Keyboard.dismiss()
            this.props.addTodo(text)
            this.setState({text: ""})
        }

        render(){
            return(
                <View style={styles.container}>
                    <TextInput 
                        style={{borderWidth:.5, width: 300, height: 40}}
                        defaultValue={this.state.text}
                        onChangeText={(value) => this.setState({text:value})}/>
                    <TouchableOpacity 
                        onPress={() => this.add(this.state.text)}>
                        <Text
                            style={{fontSize: 18}}>ADD TODO</Text>
                    </TouchableOpacity>
                    <TouchableOpacity 
                        onPress={() => this.props.navigation.navigate('Second')}>
                        <Text
                            style={{fontSize: 18}}>Second Screen</Text>
                    </TouchableOpacity>
                    <FlatList
                        data= {this.props.todos}
                        numColumns={1}
                        keyExtractor= {item => item.id}
                        renderItem ={({ item }) => 
                            <TouchableOpacity
                                onPress={() => this.props.toggleTodo(item)} 
                                style={styles.todoText}>
                                <Text style={{textDecorationLine: item.completed ? 'line-through' : 'none', fontSize: 20}}>{item.text}</Text>
                            </TouchableOpacity>
                            }
                        />                
                </View>
            )
        }
    }
    const mapStateToProps = state => ({
        todos: state.todos
    })

    const mapDispatchToProps = dispatch => ({
        addTodo: text => dispatch(addTodo(text)),
        toggleTodo: item => dispatch(toggleTodo(item))
    })


    export default connect(mapStateToProps, mapDispatchToProps)(CounterR)




    const styles = StyleSheet.create({
        container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        },
        welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
        },
        instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
        },
        todoText: {
            width: width,
            margin: 10
        }
    });

Counter.js

    import React, { Component } from 'react';
    import {View, 
        TouchableOpacity, 
        Text, 
        Dimensions,
        StyleSheet, 
        TextInput,
        FlatList,
        Keyboard} from 'react-native';
    import {connect} from 'react-redux'
    import { addTodo } from './actions/index'
    import { toggleTodo } from './actions/index'
    import { Provider } from 'react-redux'
    import store from './store/index'
    const { width, height } = Dimensions.get("window");

    export class Counter extends Component{

        state = {
            text: "",
        }

        addTodo = text => {

            Keyboard.dismiss()
            this.props.addTodo(text)
            this.setState({text: ""})

        }

        render(){
            return(
                <View style={styles.container}>
                    <TextInput 
                        style={{borderWidth:.5, width: 300, height: 40}}
                        defaultValue={this.state.text}
                        onChangeText={(value) => this.setState({text: value})}/>
                    <TouchableOpacity 
                        onPress={() => this.addTodo(this.state.text)}>
                        <Text
                        style={{fontSize: 18}}>ADD TODO</Text>
                    </TouchableOpacity>

                </View>
            )
        }
    }

    const mapStateToProps = state => ({
        todos: state.todos
    })

    const mapDispatchToProps = dispatch => ({

        addTodo: text => dispatch(addTodo(text)),
        toggleTodo: item => dispatch(toggleTodo(item))
    })


    export default connect(mapStateToProps, mapDispatchToProps)(Counter)

    const styles = StyleSheet.create({
        container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        },
        welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
        },
        instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
        },
        todoText: {
            width: width,
            margin: 10
        }
    });

app / actions / index.js

    import {Keyboard} from 'react-native'
    import { ADD_TODO, TOGGLE_TODO } from './actionTypes'
    let x = 0
    export const addTodo = (text) => ({ 
        type: ADD_TODO,
        id: x++,
        text: text
    })
    export const toggleTodo = (item) => ({

        type: TOGGLE_TODO,
        id: item.id
    })

app / actions / actionTypes.js

    export const ADD_TODO = 'ADD_TODO'
    export const TOGGLE_TODO = 'TOGGLE_TODO' 

app / reducers / index.js

    import { combineReducers } from 'redux'
    import todos from './todos'

    export default combineReducers({
        todos
    }) 

app / reducers / todos.js

    const todos = (state =[], action) => {
        switch(action.type){
            case 'ADD_TODO':
            return [
                ...state, {
                    id: action.id,
                    text: action.text,
                    completed: false
                }
            ]

            case 'TOGGLE_TODO':
            return state.map(todo => 
                (todo.id === action.id)
                ? 
                {...todo, completed: !todo.completed} 
                : 
                todo)
            default: 
                return state
        }
    }
    export default todos

app / store / index.js

    import { createStore } from 'redux'
    import rootReducer from '../reducers'

    export default store = createStore(rootReducer) 

0 个答案:

没有答案