Каждый раз, когда я отправляю действие и обновляю свой магазин, все мое приложение рендерится заново. Я предполагаю, что я делаю что-то не так с моей функцией connect / mapDispatchToProps? Правильно ли передать { ...actions }
в качестве второго аргумента моей connect
функции в App.js?
Вот мой код:
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));
действия / 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)));
};
}
редукторы / 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;
}
}
}
redurs / posts.js похож на redurs / 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;
}
}
}