【问题标题】:Dispatching to and accessing state of store on Redux (React Native) - returning undefined在 Redux (React Native) 上调度和访问 store 的状态 - 返回 undefined
【发布时间】:2020-08-26 07:56:55
【问题描述】:

尝试在我现有的一个应用程序中实现 redux(第一次)。基本上尝试做一些非常简单的事情,使用文本输入将字符串存储在存储中,然后使用 redux 将其中继回另一个组件。但是,尽管操作已调度,但当我将其记录到控制台时,我不断收到输入字符串的“未定义”。不知道我哪里错了,其他问题并没有让我的初学者头脑更清楚!

我已经定义了单个 reducer,将它们组合在一个索引中,创建了 store(传递我的组合 reducer),在我的 store 的提供程序中包装了导航(整个应用程序),创建了一个 dispatch 和 event/action 来激活 dispatch (基本上当用户输入一个字符并按下继续按钮时)。

textInputPost.js:(减速器)

const initialState = {
    textInputValue: '',
};

const textInputReducer = (state = initialState, action) => {
    console.log('textInputReducer', action);
    switch(action.type){
        case 'ADD_INPUT_TEXT':
            return { textInputValue: action.text };
        case 'RESET_INPUT_TEXT':
            return { textInputValue: ''}
    default:
        return state;
    }
}

export default textInputReducer;

index.js:(rootReducer - 组合减速器)

import { combineReducers } from 'redux';

import photoInputPost from './photoInputPost'
import cameraInputPost from './cameraInputPost'
import textInputPost from './textInputPost'

export default rootReducer = combineReducers({
    text: textInputPost
})

Index.js:(商店)

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

export default Store = createStore(rootReducer)

App.js:(提供者包裹在 React Navigation 中)

return (
            <Provider store={Store}>
                <Navigation/>
            </Provider>
        );

AddTextModal.js:(用于在 textInput 上更新存储状态的组件)

import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, KeyboardAvoidingView, TextInput } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { FontAwesome5, Feather } from "@expo/vector-icons";
import { connect } from 'react-redux'

import ModalContainer from '../../App'

class AddTextModal extends React.Component {

    continueUpload = (textInput)  => {
        this.props.addText(textInput)
        console.log(this.props.textInputValue)
        this.props.navigation.navigate('Upload')
    }

    render() {
        return(
                  <View style={{backgroundColor:"#000000CC", flex:1}}>
                    <View style={{ backgroundColor:"#ffffff", marginLeft: 0, marginRight: 0, marginTop: 180, padding: 20, borderTopLeftRadius: 20, borderTopRightRadius: 20, flex: 1, }}>
                        <View style={styles.header}>
                            <TouchableOpacity style={{position: 'absolute'}} onPress={() => this.props.navigation.navigate('Home')}>
                                <Text style={styles.buttonFont}>Back</Text>
                            </TouchableOpacity>
                            <Text style={styles.headerText}>Write Something</Text>
                            <TouchableOpacity style={{position: 'absolute', right: 0}} onPress={(textInput) => this.continueUpload(textInput)}>
                                <Text style={styles.buttonFont}>Continue</Text>
                            </TouchableOpacity>

                        </View>
                        <View style={styles.uploadTextInput}>
                            <Feather name="message-square" size={14} color="grey" />
                            <TextInput style={{paddingLeft: 5, fontSize: 14}}
                                placeholder="What do you want to say?"
                                defaultValue={this.props.textInputValue}
                                onChangeText={textInput => this.props.addText(textInput)}
                                />
                        </View>
                    </View>
                 </View>
        );
    }
}

//#6 mapStateToProps to access store from our component
function mapStateToProps(state){
    return {
        textInputValue: state.textInputValue
    }
}

//#10. matchDispatchertoProps to establish dispatcher for actions. These actions will then go to functions in the reducer to change the app state
function mapDispatchToProps(dispatch) {
    return {
        addText: () => dispatch({type: 'ADD_INPUT_TEXT'}),
    }
}

UploadScreen.js:(AddTextModal 的文本输入中继存储状态的组件)

import React from 'react';
import { Text, Image, View, TextInput, TouchableHighlight, TouchableOpacity } from 'react-native';
import { FontAwesome5, Feather } from "@expo/vector-icons";

import { connect } from 'react-redux'

import ToolbarComponent from './ToolbarComponent'
import styles from './../Styles';

import textInput from './../../containers/textInput'

class UploadScreen extends React.Component {

    uploadMedia = () => {
        //upload to DB - add to vault, home screen
        this.props.resetText()
        this.props.navigation.navigate('Home')
    }

    //viewPhoto function for viewing photo on full screen
    viewPhoto = () => {
        return
    }

    render() {
        return(
                  <View style={{backgroundColor:"#000000CC", flex:1}}>
                    <View style={{ backgroundColor:"#ffffff", marginLeft: 0, marginRight: 0, marginTop: 180, padding: 20, borderTopLeftRadius: 20, borderTopRightRadius: 20, flex: 1, }}>
                        <View style={styles.header}>
                            <TouchableOpacity style={{position: 'absolute'}} onPress={() => this.props.navigation.goBack()}>
                                <Text style={styles.buttonFont}>Back</Text>
                            </TouchableOpacity>

                            <TouchableOpacity style={{position: 'absolute', right: 10}} onPress={() => this.uploadMedia()}>
                                <Text style={styles.buttonFont}>Upload</Text>
                            </TouchableOpacity>

                            <View style={styles.uploadTextInput}>
                                    <Text>{this.props.textInputValue}</Text>
                            </View>
                        </View>
                    </View>
                 </View>
        );
    }
}

function mapStateToProps(state){
    return {
        textInputValue: state.textInputValue
    }
}

function mapDispatchToProps(dispatch) {
    return {
        resetText:() => dispatch({type: 'RESET_INPUT_TEXT'})
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(UploadScreen);

【问题讨论】:

    标签: react-native redux react-redux


    【解决方案1】:

    我相信您的问题是您没有在 mapDispatchToProps 函数中指定有效负载。尝试重写您的 mapDispatchToProps 函数,使其看起来像:

    function mapDispatchToProps(dispatch) {
        return {
            addText: (payload) => dispatch({type: 'ADD_INPUT_TEXT', payload: payload}),
        }
    }
    

    由于我将您的有效负载重命名为“payload”,因此在您的减速器中将“action.text”更改为“action.payload”:

    const initialState = {
        textInputValue: '',
    };
    
    const textInputReducer = (state = initialState, action) => {
        console.log('textInputReducer', action);
        switch(action.type){
            case 'ADD_INPUT_TEXT':
                return { textInputValue: action.payload };
            case 'RESET_INPUT_TEXT':
                return { textInputValue: ''}
        default:
            return state;
        }
    }
    
    export default textInputReducer;
    

    【讨论】:

    • 您好,谢谢您的回答。我可以看到逻辑并应用它,它让我更近了一步!我不知道为什么,但我还必须像这样对初始状态进行封装和分类; text: { textInputValue: '' } 然后通过textInputValue: state.text.textInputValue调用组件中的状态!
    猜你喜欢
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    • 2016-11-20
    • 2021-03-08
    • 2020-09-25
    相关资源
    最近更新 更多