【问题标题】:Redux mapStateToProps call only onceRedux mapStateToProps 只调用一次
【发布时间】:2019-07-13 16:07:03
【问题描述】:

在我的 react 本机应用程序中实现 redux 时遇到问题已经 2 天了。我检查了许多主题,但无法解决我的问题。

问题是 mapStateToProps 只调用一次,但在执行操作后不再调用。我的 reducer 被调用,但状态没有更新。

我使用 android studio 和模拟器在 android 上测试我的工作。

这是我的代码:

App.js:

  <Provider store={createStore(reducers)}>
    <View>
         <MainScreen />
    </View>
  </Provider>

HeaderReducer:

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case SET_HEADER:
      return action.payload;
    default:
      return state;
 }

};

reducers/index.js

import { combineReducers } from 'redux';
import HeaderReducer from './HeaderReducer';

export default combineReducers({
  headerText: HeaderReducer,
});

actions/index.js

export const SET_HEADER = 'set_header';

export const setHeaderText = (title) => {
  return {
    type: SET_HEADER,
    payload: title,
  };
};

MainScreen.js

import * as actions from '../actions';

... 
<Text> {this.props.headerText} </Text>
<Button
          onPress={() => {
            this.props.setHeaderText(`screen: ${SELECTED_PAGE.profile}`);
            this.forceUpdate();
          }}
        >

 ...

const mapStateToProps = (state) => {
  const { headerText } = state;
  return { headerText };
};

export default connect(mapStateToProps, actions)(MainScreen);

我知道我不需要在 onPress 回调中强制更新,但它只是在调用函数后检查状态。

因此,当应用程序启动时,会调用减速器并且我的 mapStateToProps 正在工作。但是当我点击我的按钮时,我的减速器被调用,好的动作在开关中执行,但我的 mapStateToProps 不再被调用。当我再次单击时,如果我 console.log 在我的减速器中记录状态,我可以看到状态没有更新,但与 INITIAL_STATE 保持相同。

我没有改变我的 reducer 中的状态,我连接了 MainScreen.js 中的所有内容,并将我的应用程序包装在 Provider with store 中。

我按照 Udemy 上的教程在我的应用程序中实现 reduc,即使我检查了 github 上 tuto 的代码,我也找不到问题出在哪里 (https://github.com/StephenGrider/ReactNativeReduxCasts/tree/master/tech_stack)

我想我错过了一些非常明显的东西,但自从 2 天以来我无法找出问题所在:/

如果有人可以提供帮助,我将不胜感激:)

谢谢。

编辑:

我没有找出问题所在,所以我只是从头开始,我做了完全一样的(THE SAAME !!),现在它正在工作......感谢您的帮助:)

【问题讨论】:

  • App.js 是你应用的入口吗?因为我认为 Provider 必须呈现在组件树的顶部。为简单起见,在创建 App.js 后,您的 index.js 看起来像(或没有):..... ReactDOM.render( &lt;App /&gt;, document.getElementById('root') ); ...... 并且 App 是从您的 App.js 导入的
  • 是的,你是对的,在我的 app.js 中有 AppRegistry.registerComponent(appName, () => App);并且 App 是从我的 App.js 导入的
  • 我真的很困惑!!!因为我在一个示例项目中做了和你一样的事情,而且效果很好。

标签: react-native redux


【解决方案1】:

首先以this.props.setHeaderText() 进行实际操作并传递标题(如果您愿意)并确保您的 INITIAL_STATE 是一个对象或 []。

const mapStateToProps = (state) => {
    return{ 
    headerText: state.headerText 
    }
    };
    export default connect(mapStateToProps, actions)(MainScreen);

【讨论】:

    【解决方案2】:

    问题在于您的HeaderReducer,reducer 期望返回一个状态对象,但您返回的是一个字符串。

    export default (state = INITIAL_STATE, action) => {
      switch (action.type) {
        case SET_HEADER:
          return action.payload;
        default:
          return state;
     }
    

    SET_HEADER的情况下,你真正想要的是覆盖一个字段而不是覆盖整个状态对象,所以改为下面

    const INITIAL_STATE = { customizeText: '' };
    
    export default (state = INITIAL_STATE, action) => {
      switch (action.type) {
        case SET_HEADER:
          return { ...state, customizeText: action.payload }; // <<=== HERE
        default:
          return state;
      }
    }
    

    然后在您的MainScreen.js 中,您必须更新您的mapStateToProps 函数

    <Text> {this.props.someText} </Text>
    ...
    const mapStateToProps = ({ headerText }) => {
      return { someText: headerText.customizeText };
    };
    
    ...
    
    

    我已更新字段名称以避免混淆

    【讨论】:

    • 你好,谢谢你的回答,我试过了,还是一样。你的意思是我的reducer必须返回一个对象,不能返回一个值(int、string、array...)?
    • @JulienRousseau:Redux 一开始可能看起来很混乱,但是一旦你理解了这个概念,它实际上就非常简单了。享受! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2019-11-10
    • 1970-01-01
    • 2018-05-10
    相关资源
    最近更新 更多