【问题标题】:react component connected, redux state changes... but no update to component?反应组件已连接,redux 状态更改...但组件没有更新?
【发布时间】:2017-10-08 10:04:34
【问题描述】:

我正在为多渠道聊天应用程序创建 React/Redux 前端。在使用 reduxreact-reduxredux-thunk 时,我在让一些 React 组件在状态更改后重新渲染时遇到问题。

我相信我的 reducer 不会发生变异,并且我是通过 react-reduxconnect 订阅的。当我运行应用程序并查看浏览器控制台时,我看到了组件的初始渲染(即初始状态为空),然后状态更改(由index.js 中的动作调度触发)......然后我会期望组件使用新的道具重新渲染,但它不会发生。

我在这里建立了一个回购: https://github.com/mattmoss/react-redux-no-update

node_modules不在repo中,所以要运行,首先下载依赖(运行yarn就足够了),然后npm start

一些摘录(请参阅 repo 中的完整源代码):

reducers/channelList.js

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

export default function channelList(state = [], action) {
    switch (action.type) {
        case c.FETCH_CHANNELS_SUCCESS:
            return action.channels;
        default:
            return state;
    }
}

actions/channelActions.js

export function fetchChannels() {
    return (dispatch) => {
        return ChannelApi.allChannels()
            .then(channels => dispatch(fetchChannelsSuccess(channels)))
            .catch(error => { throw(error); });
    };
}

export function fetchChannelsSuccess(channels) {
    return {
        type: c.FETCH_CHANNELS_SUCCESS,
        channels
    };
}

components/ChannelListView.js

class ChannelListView extends React.Component {
    render() {
        const { channels, current, onSelect } = this.props;

        console.log("channels:", channels, "current:", current);

        return (
            <ListGroup>
                {channels.map(channel =>
                    <ListGroupItem
                        key={channel.id}
                        active={channel.id === this.props.current}
                        onClick={onSelect(channel.id)}
                    >
                        <strong>#{channel.name}</strong>
                    </ListGroupItem>
                )}
            </ListGroup>
        );
    }
}

export default ChannelListView;

containers/ChannelList.js

import ChannelListView from '../components/ChannelListView';

const mapStateToProps = (state, ownProps) => {
    return {
        channels: state.channelList,
        current: state.currentChannel
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        onSelect: (id) => () => {}
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(ChannelListView);

App.js

class App extends Component {
  render() {
    return (
      <Grid>
        <Row>
          <Col>
            <h1>Channels</h1>
            <ChannelList />
          </Col>
        </Row>
      </Grid>
    );
  }
}

index.js

const store = configureStore();
store.dispatch(fetchChannels());

ReactDOM.render(
    <Provider store={configureStore()}>
        <App />
    </Provider>,
    document.getElementById('root')
);

store/configureStore.js

import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers/rootReducer';
import thunk from 'redux-thunk';
import logger from 'redux-logger';

export default function configureStore() {
    return createStore(
        rootReducer,
        applyMiddleware(thunk, logger)
    );
}

【问题讨论】:

  • 你也可以显示configureStore 吗?
  • @MichaelPeyper 编辑显示configureStore

标签: javascript reactjs redux react-redux


【解决方案1】:

我不是 100%,因为我自己对 React 还是比较陌生。但是看看你的index.js 脚本。

// You configure the store, then dispatch the fetchChannels action
const store = configureStore();
store.dispatch(fetchChannels());

ReactDOM.render(
    // But here, you're recreating the store again, which I think will re-initialise an empty store
    // Change this to use the `store` variable from above.
    <Provider store={configureStore()}>
        <App />
    </Provider>,
    document.getElementById('root')
);

【讨论】:

  • 好发现...我错过了这个,正准备设置一个 jsfiddle 来尝试解决这个问题。
  • 就是这样......你知道,戴着三焦眼镜,你会认为我的“八只眼睛”会看到这个,但没有......最后,我认为这会很愚蠢.非常感谢!
  • 不客气。在我发现这一点之前,我也看不出你写的东西有什么问题。 :)
猜你喜欢
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2018-09-25
  • 2019-05-09
  • 2019-03-10
  • 2019-10-06
  • 1970-01-01
相关资源
最近更新 更多