【发布时间】:2017-06-17 06:44:08
【问题描述】:
使用终端测试我发送的操作,Redux-logger 显示我的状态正在正确更新。但是,由于状态更改,我的组件不会重新渲染。我查看了关于组件不重新渲染的 SO 答案,大多数回复声称状态正在发生变化;因此,Redux 不会重新渲染。但是,我正在使用 Lodash 的合并来对对象进行深度复制,我很确定我没有返回修改后的对象。 (请看下面附上的sn-p)
很想听听你们的一些建议,把我的头发拉出来!
const usersReducer = (state = {}, action) => {
Object.freeze(state); // avoid mutating state
console.log(state);
// returns an empty object
let newState = merge({}, state);
console.log(newState);
// returns my state with my dispatched action object inside already???
// newState for some reason already has new dispatched action
switch (action.type) {
case RECEIVE_USER:
let newUser = {[action.user.id] = action.user};
return merge(newUser, newUser);
case RECEIVE_USERS:
newState = {};
action.users.forEach(user => {
newState[user.id] = user;
});
return merge({}, newState);
default:
return state;
}
};
反应容器组件
import { connect } from 'react-redux';
import { receiveUsers, receiveUser, refreshAll, requestUsers, requestUser } from '../../actions/user_actions';
import allUsers from '../../reducers/selectors';
import UserList from './user_list';
const mapStateToProps = (state) => ({
users: allUsers(state), // allUsers (selector that takes the state specfically the user Object and returns an array of user Objects)
state
});
const mapDispatchToProps = (dispatch) => ({
requestUser: () => dispatch(requestUser()),
requestUsers: () => dispatch(requestUsers()),
receiveUsers: (users) => dispatch(receiveUsers(users)),
receiveUser: (user) => dispatch(receiveUser(user)),
refreshAll: (users) => dispatch(refreshAll(users))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(UserList);
React 展示组件
import React from 'react';
class UserList extends React.Component {
render() {
const { users, state } = this.props;
const userItems = users.map((user, idx) => {
return(<li key={idx}>{user.username}</li>);
});
return (
<div>
<ul>
{ userItems }
</ul>
</div>
);
}
}
export default UserList;
反应商店
import { createStore, applyMiddleware } from 'redux';
import createLogger from 'redux-logger';
import RootReducer from '../reducers/root_reducer';
const logger = createLogger();
const configureStore = (preloadedState = {}) => {
return createStore(
RootReducer,
preloadedState,
applyMiddleware(logger));
};
// const configureStore = createStore(rootReducer, applyMiddleware(logger));
// oddly enough, when I have the store as a constant and not a function that returns the store constant, dispatching actions through the terminal will correctly update the state and rerender the component
export default configureStore;
反应选择器
const allUsers = ({ users }) => {
return Object.keys(users).map(id => (
users[id]
));
};
export default allUsers;
【问题讨论】:
-
你能添加你的组件代码吗?将组件连接到商店的方式可能存在问题。
-
这可能与您的问题无关,但是您对合并的任何使用对我来说都没有任何意义。您到底希望完成什么?我建议您只使用 splats,例如
return {...state, x: 42} -
在哪里添加
usersReducer到商店?您能否验证您的组件mapStateToProps在商店状态更改时是否被调用?如果不是,则可能意味着您的减速器未正确执行。 -
@Mustafa 在我的 RootReducer 我调用 CombineReducers({ users: usersReducer });我认为您正在做某事,似乎没有调用 mapStateToProps,但是当您调度操作时不会自动调用它吗?
-
@Tonyhliu 也许是因为您没有在应用程序的任何地方调用 configureStore .. 我还没有看到商店是这样创建的,所以不确定它是否可能。这个
return merge(newUser, newUser);对我来说也没有意义。
标签: reactjs redux render react-redux