组件在调度操作时不断重新呈现(承诺)

时间:2017-10-13 17:33:52

标签: reactjs redux react-router-v4

当我使用this.props.addChannel(payload);运行代码时 通道组件在无限循环中保持重新渲染。

当我用console.log(payload)替换它时,它可以正常工作。

const mapStateToProps = state => ({
    user: state.shared.user,
});

const mapDispatchToProps = dispatch => ({
    addChannel: (payload) => dispatch({type:ADD_CHANNEL, payload})
});


class Channel extends Component{

    componentDidMount(){
        const payload = api.Channels.getAll();
        this.props.addChannel(payload);
        //console.log("Channels", payload)

    }

    render(){
        return(
            <div>
            <AddChannel />
            <ChannelList channels={[{text:"test"}]} />
            </div>
        );
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Channel);

api代码:

const Channels = {
  getAll: () => requests.get('channels/twitter/')
};

减速器:

import {ADD_CHANNEL} from '../constants/ActionTypes';

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

路线组件:

import React,{Component} from 'react';
import {Route, Switch} from 'react-router-dom';
import { connect } from 'react-redux';

import Auth from './containers/Auth';
import Channel from './containers/Channel';
import Messages from './containers/Messages';
import withAuth from './components/Auth/WithAuth';

const mapStateToProps = state => ({
    user: state.shared.user,
});


class Routes extends Component{
  render(){
     const user = this.props.user;

     return (
        <Switch>
            <Route exact path='/' component={Auth} />
            <Route path='/messages' component={withAuth(Messages, user)} />
            <Route exact path='/channels' component={withAuth(Channel, user)} />
        </Switch>
    );
  }
};

export default connect(mapStateToProps, ()=>({}),null,{pure:false})(Routes);

1 个答案:

答案 0 :(得分:2)

循环的原因可能是调用NUL的{​​{1}}道具中的高阶分量withAuth。 (见Route component docs

每次呈现component时,此调用都将返回一个新组件,这将挂载一个带有随附api调用和redux存储更新的新Route。由于Routes,商店更新会触发Channel的重新呈现(即使{pure: false}没有更改)并开始循环的新周期。

如果你放弃Routes(这在这里似乎没什么用处),你可能会结束循环,但是user组件仍然会进行不必要的重新安装,如果其中一个它的祖先重新渲染,重置{pure: false}及以下的所有本地组件状态。

要解决此问题,您可以重构Channel以获取Channel作为道具而不是参数,并在withAuth类之外的顶层调用它:

user

现在,您可以使用Routes的{​​{1}}道具将const AuthMessages = withAuth(Messages); const AuthChannel = withAuth(Channel); 传递给这些组件:

user

除此之外,您可能希望保留存储中的通道并异步处理api调用,但我认为此代码更像是正在进行的工作。