react-native 中的 Redux 错误

Posted

技术标签:

【中文标题】react-native 中的 Redux 错误【英文标题】:Redux error in react-native 【发布时间】:2018-04-21 23:28:48 【问题描述】:

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

我对 redux 还很陌生。如您所知,redux 很复杂,甚至难以实现。

我按照 GitHub 和 youtube 中的一些示例开始实施它。

Actions 文件夹下 我有。以下两个文件

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】:

这里有很多东西要理解。

基本工作流程是(您可以将接收组件设置为不同的)

Component Button > Action > Reducer > Component Props > Render

要实现这一点,您需要同时设置 store 和通过 redux 调用“事件”。

下面是一个示例(如果不完美,请原谅,只是在此处输入),但其他组件从操作中获取值的方式是因为它使用“连接”HOC。每次 redux 获得状态更改时,它都会调用所有“已连接”的组件。在这里,我们获取更新后的余额并将其作为“mapStateToProps”函数的一部分返回,该函数只是使用该对象设置组件道具。然后通过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
      
   

【讨论】:

以上是关于react-native 中的 Redux 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在reducer中专门使用redux来获取react-native中的API?

connect redux函数不能与react-native一起使用

在未弹出 Redux 的情况下测试 Jest React-Native Expo CRNA

将 Redux 添加到 React-Native 应用程序?

我无法在带有 redux 的 react-native 中使用地理定位

如何在 App.js (React-Native) 中访问 redux 状态