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
发送给所有子组件。组件不应该知道任何关于状态或操作的信息。组件应该有一个清晰的界面,例如一个propisActive
和一个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
发送给所有子组件。组件不应该知道任何关于状态或操作的信息。组件应该有一个清晰的界面,例如一个propisActive
和一个onClick
处理程序。父组件应该读取状态并填充这些属性。然后,只有当组件的属性更改时,才会重新招标。如果正确操作状态,还可以将PureComponent
放在任何地方以提高性能。