商店更改时mapStateToProps不会更新

时间:2019-03-01 07:49:34

标签: react-native redux react-redux

我使用了“ react-redux”中的connect来将mapStateToProps函数链接到组件。

在安装组件时,道具正确链接,但是在商店更改时道具不会更新。

此外,当商店发生更改时,组件中的store.subscribe()会正确触发,因此操作和调度程序似乎正在工作。

调度是从componentTest进行的。

我创建了一个最小的项目来重现该问题。

App.js:

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native';

import {store} from "./store";
import TestComponent from "./TestComponent";
import {Provider} from "react-redux";

type Props = {};
export default class App extends Component<Props> {
    render() {
        return (
            <View style={styles.container}>
                <Provider store={store}>
                    <TestComponent/>
                </Provider>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
});

TestComponent.js

import React, {Component} from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {testDispatcher} from "./store";
import {connect} from "react-redux";
import {store} from './store'


class TestComponent extends Component {

    constructor(props) {
        super(props)
        this.state = {
            message: store.getState().message
        }
    }

    componentWillReceiveProps(nextProps){
        console.log("updating")
        console.log(nextProps)
    }

    componentDidMount() {
        store.subscribe(() => {
            this.setState({
                message: store.getState().message
            })
        })
    }

    render() {
        console.log(this.props)
        return (
            <View style={styles.container}>
                <TouchableOpacity
                    onPress={() => {
                        console.log("onpress")
                        store.dispatch(testDispatcher("updated value"))
                    }}
                ><Text>Test</Text></TouchableOpacity>
                <Text>data by subscribe : {this.state.message}</Text>
                <Text>data by props : {this.props.message}</Text>
            </View>
        )
    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
});


const mapStateToProps = state => {
    return {
        message: state.message
    }
}


export default connect(mapStateToProps)(TestComponent)

store.js

import {createStore} from "redux";

const TEST = "TEST"


const storeData =  {
    message: "default value"
}


export function testDispatcher(message){
    console.log("in dispatcher")
    return {
        type : TEST,
        message
    }
}


export const reducer = (state = storeData, action) => {
    switch (action.type) {
        case TEST:
            state.message = action.message
            console.log("new state", state)
            return state
        default:
            return state
    }
}

export const store = createStore(reducer)

我可能缺少明显的东西。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

错误出在减速器内部,您试图改变状态(不可变)。

export const reducer = (state = storeData, action) => {
  switch (action.type) {
     case TEST:
        return {
          ...state, // not needed here, but I add this since your production state will likely have more than just one key
          message: action.message
        };

      default:
        return state
   }
}