Redux商店无法从reducer

时间:2017-07-12 12:08:34

标签: reactjs redux react-redux

我创建了商店,但发现商店中没有状态,但减少器发送到商店有状态。 由于商店里没有州,我根本无法初始化我的组件......

以下是来自模拟器的错误消息:

error message

以下是代码:

configureStore:
import { AsyncStorage } from 'react-native';
import { applyMiddleware, createStore, compose } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import {persistStore, autoRehydrate} from 'redux-persist';
import reducers from '../reducers';

var isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent;
var logger = createLogger({
predicate: (getState, action) => isDebuggingInChrome,
    collapsed: true,
    duration: true,
});

var middlewares = compose(applyMiddleware(thunk, logger), autoRehydrate());

export default function configureStore() {
    console.log('Reducer'+reducers)

    const store = createStore(reducers, undefined, middlewares);

    persistStore(store, {storage: AsyncStorage});

  if (isDebuggingInChrome) {
      window.store = store;
  }
     return store;
}
减速器/ prepareConnect:
import * as types from '../constants/ActionTypes';

const initialState = {
    readyButtonState:false, 
    appearImage:'./img/bpm1_setwifi_unready@2x.png'
}

export default function prepareConnect(state = initialState,action) {
    switch (action.type){
        case types.CONNECT_CLICK_READY: {
            return Object.assign({},state,{
                readyButtonState:action.currentState,
                appearImage:action.currentImage,
            })
        }
            break;
        default:
            return state;
            break;
    }
}
减速器/指数
import { combineReducers } from 'redux';
import prepareConnect from './prepareConnect';

const rootReducer = combineReducers({
    prepareConnect
});

export default rootReducer;
这是容器/ prepareConnectView
import React, {Component} from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import {
    StyleSheet,
    View
} from 'react-native';

import Actions from '../actions';

import Upper from "../components/prepareConnect-view/Upper";
import Bottom from "../components/prepareConnect-view/Bottom";

class PrepareConnectView extends Component {
    static props = {}

constructor(props) {
    super(props);
    this.state = {}
}

render() {
    return (
        <View>
            <Upper/>
            <Bottom {...this.props}/>
        </View>
    )
}
}

function mapStateToProps(state) {
    return {
        buttonState: state.readyButtonState,
        appearImage: state.appearImage,
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(Actions, dispatch)
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(PrepareConnectView);
这是component / prepareConnect / Bottom
import React, {Component} from 'react';
import {
    StyleSheet,
    Image,
    TouchableOpacity,
    View,
    Text,
    Button,
} from 'react-native';

import screenRelated from '../../Macro&Const/UIConst'
import BasicStyle from '../../styles/Basic'

class Bottom extends Component {
static props = {
    isClick:false,
}

constructor(props) {
    super(props);
    this.state = {
            isClick:false,
    }
}

_onPressButton = () =>{
    //TODO:点击的时候去创建Action, 并且Dispatch
    //FIXME: 为什么这里去传递的参数给不到actionCreator里面
    //发现压根在用的时候就是undefined, 为什么拿不到, 明明已经写了是False了.
    this.props.isClick = !this.props.isClick;
    this.setState({
        isClick:!this.state.isClick,
    })
    this.props.actions.connectReadyClick( this.state.isClick)
}

_nextButtonClick = () =>{
    //TODO: 只要能点击 就是跳进下一个界面
}

render() {
    return (
        <View style={BasicStyle.container}>
            <TouchableOpacity onPress={this._onPressButton}
                              style={styles.upperButton}>
                <View style={styles.innerContainer}>
                    <Image
                        style={styles.image}
                    source={require(this.props.appearImage)}/>
                    <Text style={styles.text}>Ready to connect</Text>
                </View>
            </TouchableOpacity>
            <View style={styles.nextButton}>
                <Button onPress={this._nextButtonClick}
                        disabled={!this.props.buttonState}
                        title='Next'
                        color='red'
                        style={styles.nextButton}/>
            </View>
        </View>
    )}
}

const styles = StyleSheet.create({
    innerContainer: {
        flex: 1,
        justifyContent: 'center',
        flexDirection: 'column',
    },
    image:{
        left:10,
        height:20,
        width:140,
    },
    text:{
        position:'relative',
        color: '#AEAEAE',
        left:22,
    },
upperButton:{
    flex:1,
    justifyContent:'center',
},
    nextButton:{
        position:'absolute',
        top:230,
        width:screenRelated.screenWidth+10,
        alignItems:'center',
        borderColor: 'blue',
        borderWidth: 1,
        borderRadius: 4,
    }
})

export default Bottom;

1 个答案:

答案 0 :(得分:0)

我创建了一个代码段。保持不起作用,因为在堆栈片段中没有localStorage,但这不应该擦除您的商店。所以你可以看到,你的商店里有一个初始状态。打开控制台,查看输出。

首先尝试修复错误,看看是否有帮助。你重新启动了包装工具吗?您是否在其余代码中的任何位置使用require()

&#13;
&#13;
const {combineReducers, applyMiddleware, createStore, compose} = Redux;
const thunk = ReduxThunk.default;
const {persistStore, autoRehydrate} = ReduxPersist;

const initialState = {
    readyButtonState:false, 
    appearImage:'./img/bpm1_setwifi_unready@2x.png'
}

const prepareConnect = (state = initialState, action)  => {
  switch (action.type) {
    case 'a type': {
      return Object.assign({},state, {
                  readyButtonState: action.currentState,
                  appearImage: action.currentImage,
      })
      break;
    }
    default:
      return state;
      break;
 }
};

const rootReducer = combineReducers({
    prepareConnect
});

var logger = reduxLogger.createLogger({
  predicate: (getState, action) => true,
  collapsed: true,
  duration: true,
});

var middlewares = compose(applyMiddleware(thunk, logger), autoRehydrate());

const store = createStore(rootReducer, undefined, middlewares);

persistStore(store);

const state = store.getState();

console.log("STATE:", state);
&#13;
<p id="store"></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.1/redux.js"></script>
<script src="https://unpkg.com/redux-logger@3.0.6/dist/redux-logger.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux-thunk/2.2.0/redux-thunk.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux-persist/4.8.2/redux-persist.js"></script>
&#13;
&#13;
&#13;

修改

我也创造了一个小提琴,因为localStorage在那里工作: https://jsfiddle.net/ow4z71ac/

正如您在控制台中看到的那样,您的商店按预期进行了初始化。它看起来像这样:

{
    "prepareConnect": {
        "readyButtonState": false,
        "appearImage": "./img/bpm1_setwifi_unready@2x.png"
    }
}

<强> EDIT2:

将状态映射到道具的方式无效。看看你的rootReducer。您传递给combineReducer的每个减速器的名称将被视为商店顶层的密钥。

const rootReducer = combineReducers({
    prepareConnect
});

这就是为什么你的商店看起来像这样:

{
    "prepareConnect": {
        "readyButtonState": false,
        "appearImage": "./img/bpm1_setwifi_unready@2x.png"
    }
}

这就是你尝试将你的州映射到道具的方式:

function mapStateToProps(state) {
    return {
        // readyButtonState does not exist in state but in state. prepareConnect.readyButtonState
        buttonState: state.readyButtonState,
        appearImage: state.appearImage,
    };
}

这也是require()来电失败的原因,因为this.props.appearImageundefined

您可以通过在导入时重命名reducer或通过定义自己的键来更改reducer创建的状态部分:

import initial from './prepareConnect';

const rootReducer = combineReducers({
    initial
});

import prepareConnect from './prepareConnect';

const rootReducer = combineReducers({
    initial: prepareConnect
});

然后,您可以在state.initial

中访问您的初始数据