反应原生的Redux错误

时间:2017-11-09 04:28:23

标签: react-native redux react-redux jsx redux-thunk

我正在尝试实现redux以在多个屏幕中显示平衡,因为我在单个屏幕中更新余额,它应该反映在所有其他屏幕/组件中。

我对redux很新。如你所知,redux的复杂性,甚至难以实现它。

我在GitHub和youtube上关注了一些例子并开始实现它。

操作文件夹下,我有。以下两个文件

counteractions.js

 
import * as types from './actionTypes.js';

//ActionCreator methods

export function updateBalance(balanceInfo) {

    return {
        type: types.LEDGER_BALANCE,
        payLoad: { balanceInfo }
    }
}

在Reducers文件夹下。我有这个文件

balance.js

import * as types from '../actions/actionTypes.js';

const initialState = {
    balance: 0
}

// reducer  functions .. accepts  current/initial state , actions and  returns new state

const balanceReducer=(state,action)=>
{
    switch (action.type) {
        case types.LEDGER_BALANCE:
            return {
                balance: action.payload.balanceInfo
            }
            break;
        default:
            break;
    }
}

export default balanceReducer;

在ConfigureStore.js

从'redux'导入{createStore}; 从'./reducers/index.js'中导入rootReducer;

import balanceReducer from './reducers/balance.js';

const initailState = {
    balance: 0,
}

export const store=createStore(balanceReducer,balanceReducer);

App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import { Provider } from 'react-redux';
//Provider - makes redux store  available to connect() class in component hierarchy below
import { applyMiddleware, createStore, compose, combineReducers } from "redux";
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from './reducers/index.js';
//import store from './configureStore.js';

import {
  Platform,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput
} from 'react-native';
import ReduxDemo from "./reduxDemo.js";
import { store, reducer } from './balanceDemo.js';

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
  'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
  'Shake or press menu button for dev menu',
});

export default class App extends Component<{}> {

  constructor(props) {
    super(props);
    this.state = {
      balancelocal: '',
    }
  }



  _updateLedger = () => {
    // store.dispatch({ type: 'BALANCE', payLoad: '500' });
    store.dispatch({ type: 'BALANCE', payLoad: 'Your balance is 8000 MUR' });
  }


  render() {

    store.subscribe(() => {

      this.setState({
        balancelocal: store.getState(),
      })
      //this.balanceInfo = store.getState().balance;
     // alert(this.state.balancelocal);
    });
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this._updateLedger}>
          <Text>Update balance</Text>
        </TouchableOpacity>

        <TextInput style={{height:100,width:400}} value={this.state.balancelocal}/>
      </View>
    );
  }
}

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,
  },
});

我还没有完成配置存储文件。和。我在想。我必须订阅和发送行动..

我想通过app.js点击按钮来更新余额 我有。自动更新另一页的余额..

请指导我理解并实现redux。请建议更好的文件夹结构和更好的实现redux的方法。

1 个答案:

答案 0 :(得分:0)

这里有很多东西要理解。

基本工作流程是(您可以将接收组件作为另一个组件)

Component Button > Action > Reducer > Component Props > Render

要实现这一目标,您需要设置商店和通过redux调用“事件”。

下面是一个例子(如果不完美,可以在这里输入),但是其他组件从动作中获取值的方式是因为使用'connect'HOC 。每当redux获得状态更改时,它都会调用所有“连接”的组件。在这里,我们获取更新的余额并将其作为“mapStateToProps”函数的一部分返回,该函数只是使用该对象设置组件props。然后通过this.props.balance访问余额并显示。

如果要在操作中调用api并将结果存储在reducer中,这将变得更有用。然后,所有连接的组件将获得新数据。

注1:我只使用redux-thunk中间件发送,请原谅我使用它。

注2:这是一个简单的例子。当应用程序变得更好时,您将需要防止过度呈现,因为任何reducer更改都将调用所有连接的组件。我在这里使用reselect

<强>设置

reducers.js

import { combineReducers } from 'redux';
import { balanceReducer } from 'balanceReducer';
export default combineReducers({
    balanceReducer
})

store.js

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk'

import combineReducers from './reducers'

export default function configureStore() {
  let store = createStore(combineReducers, applyMiddleware(thunk));
  return store;
}

index.js

import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
import { Provider } from 'react-redux';

import configureStore from './store';
import Component1 from './component1';

const store = configureStore()

const myapp = () => (
  <Provider store={store}>
    <View>
        <Component1 />
    <View>
  </Provider>
)

AppRegistry.registerComponent('myapp', () => myapp);

<强>零件

component1.js(关键部分是连接HOC)

import { connect } from 'react-redux';
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';  
import { updateBalance } from './action';

class Component1 extends Component {

    _updateLedger = () => {
        this.props.updateBalance(500);
    }
    render() {
       const { balance } = this.props;
       return (
          <View>
            <TouchableOpacity onPress={this._updateLedger}>
              <Text>Update balance</Text>
            </TouchableOpacity>
            <Text>{balance}</Text>
          </View>
       )
    }
}

function mapStateToProps(state) {
   return {
       balance: state.balanceReducer.balance
   }
}

function mapDispatchToProps(dispatch) {
  return {
      updateBalance = (balanceInfo) => dispatch(updateBalance(balanceInfo))
  };
}

export default connect(
  mapStatetoProps,
  mapDispatchToProps
)(Component1)

action.js

export function updateBalance(balanceInfo) {

    return {
        type: types.LEDGER_BALANCE,
        payLoad: { balanceInfo }
    }
}

balanceReducer.js(此处的关键部分是返回新状态)

const initialState = {
    balance: 0,
}
export function balanceReducer(state = initialState, action) {
   if(action.type === types.LEDGER_BALANCE) {
      return {
          balance: action.payLoad.balanceInfo
      }
   }
}