每次我发送动作并更新商店时,我的整个应用都会重新呈现。我假设我做错了w / connect / mapDispatchToProps函数?将{ ...actions }
作为第二个参数传递给App.js中的connect
函数是否正确?
这是我的代码:
class App extends Component {
componentDidMount() {
this.props.fetchPages(api.API_PAGES);
this.props.fetchPosts(api.API_POSTS);
window.addEventListener('resize', () => {
this.props.resizeScreen(window.innerWidth);
});
}
render() {
return (
<div>
{this.props.app.showIntro && <Intro {...this.props} endIntro={this.props.endIntro} />}
{!this.props.pages.isFetching && this.props.pages.data &&
<div>
<Navbar {...this.props} />
<Layout {...this.props}>
<Switch location={this.props.location}>
<Route
path={routes.HOME}
exact
component={() => (
<Home {...this.props} />
)}
/>
<Route
path={routes.ABOUT}
component={() => (
<About {...this.props} />
)}
/>
<Route
path={routes.NEWS}
exact
component={() => (
<News {...this.props} />
)}
/>
<Route
component={NotFound}
/>
</Switch>
</Layout>
</div>
}
</div>
);
}
}
function mapStateToProps(state) {
return {
app: state.app,
pages: state.pages,
posts: state.posts
};
}
export default withRouter(connect(
mapStateToProps,
{ ...actions }
)(App));
actions / index.js
export function resizeScreen(screenWidth) {
return {
type: types.RESIZE_SCREEN,
screenWidth
};
}
export function endIntro() {
return {
type: types.END_INTRO,
showIntro: false
};
}
export function toggleNav(bool) {
return {
type: types.TOGGLE_NAV,
navOpen: bool
};
}
export function toggleVideoPlayer(bool) {
return {
type: types.TOGGLE_VIDEO_PLAYER,
videoIsPlaying: bool
};
}
export function toggleScroll(bool) {
return {
type: types.TOGGLE_SROLL,
disableScroll: bool
};
}
// pages
function requestPages() {
return {
type: types.REQUEST_PAGES
};
}
function receivePages(data) {
return {
type: types.RECEIVE_PAGES,
data
};
}
// posts
function requestPosts() {
return {
type: types.REQUEST_POSTS
};
}
function receivePosts(data) {
return {
type: types.RECEIVE_POSTS,
data
};
}
// creators
export function fetchPages(path) {
return (dispatch, getState) => {
const { pages } = getState();
if (pages.isFetching) return;
dispatch(requestPages());
fetch(`${process.env.API_URL}${path}`)
.then(response => response.json())
.then(json => dispatch(receivePages(json)));
};
}
export function fetchPosts(path) {
return (dispatch, getState) => {
const { posts } = getState();
if (posts.isFetching) return;
dispatch(requestPosts());
fetch(`${process.env.API_URL}${path}`)
.then(response => response.json())
.then(json => dispatch(receivePosts(json)));
};
}
reducers / app.js:
const initialState = {
screenWidth: typeof window === 'object' ? window.innerWidth : null,
showIntro: true,
navOpen: false,
videoIsPlaying: false,
disableScroll: false
};
export default function app(state = initialState, action) {
switch (action.type) {
case RESIZE_SCREEN: {
return {
...state,
screenWidth: action.screenWidth
};
}
case TOGGLE_NAV: {
return {
...state,
navOpen: !state.navOpen
};
}
case END_INTRO: {
return {
...state,
showIntro: false
};
}
case TOGGLE_VIDEO_PLAYER: {
return {
...state,
videoIsPlaying: !state.videoIsPlaying
};
}
case TOGGLE_SCROLL: {
return {
...state,
disableScroll: !state.disableScroll
};
}
default: {
return state;
}
}
}
reducers / posts.js与reducers / pages.js类似:
const initialState = {
isFetching: false
};
export default function posts(state = initialState, action) {
switch (action.type) {
case REQUEST_POSTS: {
return {
...state,
isFetching: true
};
}
case RECEIVE_POSTS: {
return {
...state,
isFetching: false,
data: action.data
};
}
default: {
return state;
}
}
}
答案 0 :(得分:1)
如果在每次Redux更新中重新渲染过多的应用程序时遇到问题,则有助于使用更多连接的组件并限制传递给每个组件的状态量。我看到您正在将道具分散到每一页中,这很方便,但这是重新渲染效率低下的常见原因。
<Home {...this.props} />
<About {...this.props} />
<News {...this.props} />
这可能会导致将过多的数据传递给这些组件中的每个组件,并且每个redux操作都会导致整个页面重新呈现。
我看到的另一个潜在问题是您使用内联匿名函数作为路由的组件回调
<Route
path={routes.ABOUT}
component={() => (
<About {...this.props} />
)}
/>
我不太确定React Router在这里如何工作,但是潜在的问题是,路由器每次重新渲染时,这些匿名功能都会重新创建。 React会将它们视为新组件,并强制进行重新渲染。您可以通过以下方式解决此问题:将这些组件中的每个组件拉入各自的道具,然后像这样更新路由器
<Route
path={routes.ABOUT}
component={ConnectedAbout}
/>
答案 1 :(得分:1)
这是redux的工作方式:道具正在更改,因此所连接的组件将被重新更改。
您可以:
shouldComponentUpdate
以限制重新呈现( note :这也将阻止子组件)Component
基类,以便切换到浅表比较