使用Redux

时间:2016-11-11 17:10:42

标签: react-native redux react-redux

我正在使用React Native + Redux创建某种实时聊天应用程序。当我从websocket获得一些新消息时,在内部它将使用redux store更新消息列表作为数组。这看起来像是:

import { CHAT_INIT, CHAT_RECV } from '../actions/Chat';

const defaultState = {
    chatList: []
};

export default function(state = defaultState, action = {}) {
    switch(action.type) {
        case CHAT_INIT:
            return Object.assign({}, {
                chatList: []
            });
        case CHAT_RECV:
            let chatList = state.chatList;
            chatList.push(action.data);
            return Object.assign({}, {
                chatList: chatList
            });
        default:
            return state;
    }
}

只有两个动作:CHAT_INIT和CHAT_RECV可以很容易理解。

当应用程序从套接字收到新消息时,它将使用“CHAT_RECV”操作调用store.dispatch。这是消息列表的组件代码:

class ChatList extends Component {
    static propTypes = {
        chatList: React.PropTypes.array
    }
    static defaultProps = {
        chatList: []
    }
    componentWillMount() {
        store.dispatch({
            type: ChatActions.CHAT_INIT,
            data: ''
        });
    }
    componentWillReceiveProps(nextProps) {
        console.log('will receive props');    // 1
    }
    render() {
        console.log('<ChatList />::chatList', this.props.chatList);   // 2

        return (
            <View style={styles.chatList}>
                <Text>ChatList</Text>
            </View>
        );
    }
}

export default connect(state => {
    let chatList = state.ChatReducer.chatList;
    console.log('Got:', chatList);   // 3

    return {
        chatList: state.ChatReducer.chatList
    };
})(ChatList);

我将ChatList组件与ChatReducer.chatList连接,所以当新消息到达时,ChatList组件的道具将会更新。

问题是ChatList组件上的道具根本没有更新!如您所见,我放置了很多console.log来跟踪问题所在。为了便于说明,只需添加console.log旁边的数字。

你可以看到我正在尝试更新连接组件ChatList的chatList道具,它应该在接收新道具时重新呈现(意味着新消息)。

所以[3]的console.log也打印'Got:[...,...]',但[1]和[2]不打印任何东西!这意味着ChatList组件没有正确接收下一个道具。

我仔细检查了代码并试图解决这个问题,但没有多少工作。这是Redux或React-Redux模块的问题吗?以前我将这两个模块用于我的Electron ChatApp,它没有任何问题。

有没有我遗漏的东西?我真的不知道是怎么回事。任何人都知道这个问题,请给我一个手,并将非常感激。

P.S。这些是其他组件代码。我认为这并不重要,但我只是将其粘贴给想知道的人。

高级组件:App.js

export default class App extends Component {
    componentDidMount() {
        init();        // this invokes CHAT_INIT action.
    }
    render() {
        return (
            <Provider store={store}>
                <ChatApp />
            </Provider>
        );
    }
}

实际呈现ChatList组件的ChatApp.js:

class ChatApp extends Component {
    render() {
        return (
            <View style={styles.container}>
                <NavBar username={this.props.username} connected={this.props.connected} />
                <ChatList connected={this.props.connected} />
                <ChatForm connected={this.props.connected} />
            </View>
        );
    }
}

export default connect(state => {
    return {
        username: state.UserReducer.username,
        connected: state.NetworkReducer.connected
    };
})(ChatApp);

1 个答案:

答案 0 :(得分:2)

你在这里改变你的状态:

case CHAT_RECV:
        let chatList = state.chatList;
        chatList.push(action.data);
        return Object.assign({}, {
            chatList: chatList
        });

相反,请执行:

case CHAT_RECV:
        let chatList = state.chatList.concat(action.data);
        return Object.assign({}, {
            chatList: chatList
        });