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)
);