Javascript 使用mapStateToProps基于动态路由参数渲染组件并重新选择
我正在将各种Javascript 使用mapStateToProps基于动态路由参数渲染组件并重新选择,javascript,reactjs,redux,react-redux,reselect,Javascript,Reactjs,Redux,React Redux,Reselect,我正在将各种房间的数据存储在一个全局应用程序容器中。我有一个名为roomDetails的子容器,它使用重新选择选择器从全局状态中使用ownProps.params.slug选择房间。这是使用MapStateTops完成的 我的问题是,当我从以下位置更改路由参数(rooms/:roomId)时: rooms/roomid1 到 rooms/roomid2 组件室道具未更新 我正在使用链接更改路线: 1号房间 当管线参数更改时,如何让组件的房间道具从全局房间状态重新选择房间 请注意,房间道具在第一页
房间的数据存储在一个全局应用程序容器中。我有一个名为roomDetails
的子容器,它使用重新选择选择器从全局状态中使用ownProps.params.slug
选择房间。这是使用MapStateTops完成的
我的问题是,当我从以下位置更改路由参数(rooms/:roomId
)时:
rooms/roomid1
到
rooms/roomid2
组件室道具未更新
我正在使用链接更改路线:
1号房间
当管线参数更改时,如何让组件的房间道具从全局房间状态重新选择房间
请注意,房间道具在第一页加载时会加载,或者如果我转到动态路由之外的路由,然后返回。在同一动态路由之间切换时,它们只是无法正确加载,因为只有组件属性(路由参数)在更改
RoomDetails/index.js
const mapStateToProps = (state, ownProps) => {
return createStructuredSelector({
room: selectRoom(ownProps.params.roomId),
});
}
import { createSelector } from 'reselect';
const selectGlobal = () => (state) => state.get('global');
const selectRooms = () => createSelector(
selectGlobal(),
(globalState) => globalState.get('rooms')
);
const selectRoom = (roomId) => createSelector(
selectRooms(),
(roomsState) => roomsState && roomsState.get(roomId)
);
重新选择将只响应传递给第一个参数的任何变量。因此,每当路由发生更改时,必须更新某些变量。我想到了两个选项:
- 在选择器中实现并响应它
- 发送一个事件,更新商店中安装在该路径上的组件的
roomId
对于第二个选项,您可以这样做。假设此组件安装在路径/rooms/:roomId
:
class Rooms extends Component {
changeRoom = (roomId = this.props.roomId) => this.props.setRoom(roomId);
componentDidMount() {
this.changeRoom();
}
componentWillReceiveProps(nextProps) {
if (this.props.roomId !== nextProps.roomId) {
this.changeRoom(nextProps.roomId);
}
}
}
假设此更新state.room.selected
。您可以在选择器中指定
import { createSelector } from 'reselect';
const getRooms = state => state.rooms.data;
const getSelected = state => state.rooms.selected;
export const getCurrentRoom = createSelector(
[ getRooms, getSelected ],
(rooms, selected) => rooms.find(room.id === selected)
)
我从selectRoom
中删除了参数,并将MapStateTops
更改为:
const mapStateToProps = createStructuredSelector({
room: selectRoom(),
});
然后我像这样更新了选择器,它正在工作
const selectGlobal = () => (state) => state.get('global');
const selectedRoom = () => (state, props) => props && props.params.roomId;
const selectRooms = () => createSelector(
selectGlobal(),
(globalState) => globalState.get('rooms')
);
const selectRoom = () => createSelector(
selectRooms(),
selectedRoom(),
(roomsState, roomId) => roomsState.get(roomId)
);
我仍然不明白为什么在我向它传递props.params.roomId
时没有调用选择器
可能因为selectRooms()
没有参数,所以它总是被调用?选择器“selectRooms”不应该响应吗,因为我传递给它的内容(ownProps.params.roomId)正在更改?你能用console.log来确认它正在更改吗?当我这样做时,“componentWillReceiveProps(nextProps){console.log('Next room:',nextProps.params.roomId);}”,每次我点击一个链接更改房间时,它都会打印正确的房间id。props.params.roomId(route param)正在更新,但是props.params.roomd没有更新。我的意思是,将其记录在选择器中。例如:(rooms,selected)=>{console.log(rooms,selected);return rooms.get(selected)}
const selectGlobal = () => (state) => state.get('global');
const selectedRoom = () => (state, props) => props && props.params.roomId;
const selectRooms = () => createSelector(
selectGlobal(),
(globalState) => globalState.get('rooms')
);
const selectRoom = () => createSelector(
selectRooms(),
selectedRoom(),
(roomsState, roomId) => roomsState.get(roomId)
);