Reactjs React Redux商店更新重新发布整个应用程序

Reactjs React Redux商店更新重新发布整个应用程序,reactjs,redux,react-router,react-redux,Reactjs,Redux,React Router,React Redux,在onClickSigninButton上,调用ONTOGGLE\u MODAL\u SIGNIN,从存储中更新ui.isSigninModalActive。一切正常,但我看到当ui.issignimodalactive打开和关闭时,我的整个应用程序都会重新呈现。这是正常的行为吗?我原以为你必须存储。订阅并更新该组件的内部状态,当存储更新时,只有该组件得到更新(而不是整个应用程序)。如果整个应用程序重新呈现,那么store.subscribe有什么意义?还是我在什么地方搞砸了?提前谢谢你的帮助

onClick
SigninButton
上,调用
ONTOGGLE\u MODAL\u SIGNIN
,从存储中更新
ui.isSigninModalActive
。一切正常,但我看到当
ui.issignimodalactive
打开和关闭时,我的整个应用程序都会重新呈现。这是正常的行为吗?我原以为你必须
存储。订阅
并更新该组件的内部状态,当存储更新时,只有该组件得到更新(而不是整个应用程序)。如果整个应用程序重新呈现,那么
store.subscribe
有什么意义?还是我在什么地方搞砸了?提前谢谢你的帮助

signin_button.jsx

import React, { Component } from 'react';
import { store } from '../../../store/store';
import { onToggleModal } from '../../../actions/ui';

export const SigninButton = () => (
  <svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" className="signin-button"
           onClick={ () => store.dispatch(onToggleModal('signin')) }>
    <path d="M0 0h24.997C25.55 0 26 .444 26 1c0 .552-.45 1-1.003 1H0V0"/>
  </svg>
);
ui_store.js

export const ui = {
  isSigninModalActive: false,
};
root_reducer.js

import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import { ui } from './ui_reducer';

export const rootReducer = combineReducers({ ui, routing: routerReducer });
import update from 'immutability-helper';
import { toggleBodyOverflow } from '../modules/toggle_body_overflow';

export const ui = (state = null, action) => {
  switch (action.type) {
    case 'ONTOGGLE_MODAL_SIGNIN': {
      toggleBodyOverflow(!state.isSigninModalActive);
      document.getElementById('signin-modal__container').classList.toggle('active');
      return update(state, { isSigninModalActive: { $set: !state.isSigninModalActive } });
    }
    default: return state;
  }
};
ui_reducer.js

import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import { ui } from './ui_reducer';

export const rootReducer = combineReducers({ ui, routing: routerReducer });
import update from 'immutability-helper';
import { toggleBodyOverflow } from '../modules/toggle_body_overflow';

export const ui = (state = null, action) => {
  switch (action.type) {
    case 'ONTOGGLE_MODAL_SIGNIN': {
      toggleBodyOverflow(!state.isSigninModalActive);
      document.getElementById('signin-modal__container').classList.toggle('active');
      return update(state, { isSigninModalActive: { $set: !state.isSigninModalActive } });
    }
    default: return state;
  }
};
ui_action.js

export const onToggleModal = modal => ({ type: `ONTOGGLE_MODAL_${modal.toUpperCase()}` });
编辑:我找到了应用程序重新呈现的原因

在我的应用程序容器上,我设置了
mapstatetops
,并将
state.ui
作为道具发送到组件中。我通过移除它来“修复”它。这是停止重新呈现整个应用程序的正确方法吗

app_container.js

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as ui from '../../actions/ui';
import { App } from '../layouts/app_layout';

// problem: const mapStateToProps = state => { ui: state.ui };
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch => bindActionCreators(ui, dispatch);

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

UH我现在还不能确定为什么整个应用程序都在重新渲染,但是现在你的reducer是非常错误的。它绝对不应该修改DOM!!!。首先,在React应用程序中,直接DOM操作是错误的方法。第二,reducer只应该基于状态和动作参数创建新值,而不需要修改任何内容。哦,我明白了!谢谢那么,我是否应该在
signin_modal.jsx
组件上
store.subscribe
,并将其本地状态更改为等于
store.ui.issignimodalactive
以重新渲染?我还发现了为什么整个应用程序都在重新渲染。我“修好”了,但你能看一下吗?我将在一分钟内编辑上面的帖子。@cocacrave不使用
store。订阅
。这就是
connect
为您所做的。您的reducer应该只返回
{active:true}
{active:false}。
然后您的根组件应该从
connect
获取此状态作为属性,并将其传递给子组件。@Sulthan抱歉,您能帮我一点忙吗?在根组件中,
app\u container
中,如果我将道具
ui
对象发送给子组件,那么当
ui.active
开关时,整个应用程序将重新呈现。换句话说,存储的ui对象中的任何更改都会重新呈现整个应用程序,因为根组件中的状态as prop发生了更改。这应该发生吗?它不应该只更新一个子组件,而不更新同一父组件下的无关组件吗?这就是为什么我在子组件中使用了
store.subscribe
,并将状态作为道具删除。你建议我怎么做?@Coccarave你应该只发送需要的东西。不要将整个
ui
发送给所有子组件。组件不应该知道任何关于状态或操作的信息。组件应该有一个清晰的界面,例如一个prop
isActive
和一个
onClick
处理程序。父组件应该读取状态并填充这些属性。然后,只有当组件的属性更改时,才会重新招标。如果您正确地操作状态,您还可以将
PureComponent
放在任何地方以提高性能。嗯。。。我现在还不能确定为什么整个应用程序都在重新渲染,但是现在你的reducer是非常错误的。它绝对不应该修改DOM!!!。首先,在React应用程序中,直接DOM操作是错误的方法。第二,reducer只应该基于状态和动作参数创建新值,而不需要修改任何内容。哦,我明白了!谢谢那么,我是否应该在
signin_modal.jsx
组件上
store.subscribe
,并将其本地状态更改为等于
store.ui.issignimodalactive
以重新渲染?我还发现了为什么整个应用程序都在重新渲染。我“修好”了,但你能看一下吗?我将在一分钟内编辑上面的帖子。@cocacrave不使用
store。订阅
。这就是
connect
为您所做的。您的reducer应该只返回
{active:true}
{active:false}。
然后您的根组件应该从
connect
获取此状态作为属性,并将其传递给子组件。@Sulthan抱歉,您能帮我一点忙吗?在根组件中,
app\u container
中,如果我将道具
ui
对象发送给子组件,那么当
ui.active
开关时,整个应用程序将重新呈现。换句话说,存储的ui对象中的任何更改都会重新呈现整个应用程序,因为根组件中的状态as prop发生了更改。这应该发生吗?它不应该只更新一个子组件,而不更新同一父组件下的无关组件吗?这就是为什么我在子组件中使用了
store.subscribe
,并将状态作为道具删除。你建议我怎么做?@Coccarave你应该只发送需要的东西。不要将整个
ui
发送给所有子组件。组件不应该知道任何关于状态或操作的信息。组件应该有一个清晰的界面,例如一个prop
isActive
和一个
onClick
处理程序。父组件应该读取状态并填充这些属性。然后,只有当组件的属性更改时,才会重新招标。如果正确操作状态,还可以将
PureComponent
放在任何地方以提高性能。