设置平面对象不变记录没有问题。但是现在我有一个问题想要设置记录,我想也许是记录列表?我正在尝试将我的Firebase数据库中的User引用添加到一个或多个不可变记录中。
因此,我从firebase加载了用户参考。它的结构看起来像。
我不知道如何嵌套列表。用户具有UID的列表。从那里变得更加讨人喜欢。但这是否有可能有记录列表?我还没有在网上看到任何示例,所以现在我迷路了。任何帮助将不胜感激。
如果我只是在做个人简介之类的事情,那会看起来很像
export const Profile = Record({
key: null,
profileName: '',
profilePic: '',
teamName: '',
});
似乎很难超越UID列表,这是我遇到的第一个挑战。一旦超过了初始列表,它就会变得讨人喜欢。
也许我什至不应该做这个一成不变的事情。我欢迎其他人建议如何处理此数据。目前,我只是习惯于在应用程序中使用不可变记录。希望我最后一刻都坚持这种模式。
答案 0 :(得分:1)
基本上没有记录列表。据我所知,您可以将map与记录值一起使用,并根据this的答案扩展Record类,以获取与您想要的等效(以下代码基于此方法)。
我还可以找到一篇有趣的文章,它以一种功能性的方式针对同一想法here采用了多种方法。
如果这不是您所期望的,请告诉我。
var users = {
'efbluh': {
'profile': {
profileName: 'bill',
profilePic: 'https://blue',
teamName: 'locals',
},
'team': {
'Lpphasd' : {
competitorKey: 'a'
}
}
},
'fixbluh': {
'profile': {
profileName: 'bill',
profilePic: 'https://blue',
teamName: 'locals',
},
'team': {
'Lpphasd' : {
competitorKey: 'a'
},
'asdsadasda' : {
competitorKey: 'b'
}
}
}
};
var ProfileRecord = Immutable.Record({
profileName: '',
profilePic: '',
teamName: '',
});
var teamRecord = Immutable.Record({
competitorKey: ''
});
class User extends Immutable.Record({'profile': new ProfileRecord(), 'team':Immutable.Map()}) {
constructor({profile, team} = {}) {
super({team: Immutable.Map(team).map(x=>new teamRecord(x)), profile: new ProfileRecord(profile)})
}
}
var userMap = Immutable.Map(users).map(x=>new User(x));
// Verify that it's really a record
console.log(userMap.get('efbluh').get('profile').profileName)
console.log(userMap.get('fixbluh').toJS())
console.log(userMap.get('fixbluh').get('team').toJS())
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.4/immutable.min.js"></script>
答案 1 :(得分:0)
羞怯的建议绝对正确,因此这是公认的答案。如果您有需要,大多数人应该可以采用。但是,如果您像我一样,并且将redbase和选择器与firebase一起使用,则这里是Shyams建议对我有效的方式。我并没有声称它是您见过的最纯粹的react / redux / selectors示例,但它对我有用。
事不宜迟。
最初,我是从redux动作和reducer获取用户的。
我的动作和动作创建者从firebase中获取数据,并将其最初存储在我拥有的一些高级firebase db函数中的键值不可变记录中。
import * as types from './actionTypes';
import { Record } from 'immutable';
import { FirebaseList } from 'src/firebase';
export const League = new Record({
key: null,
value: null
})
export const leagueFireDB = new FirebaseList({
onLoad: loadLeagueSuccess,
},League);
export function loadLeague() {
console.log("LOADLEAGUE::");
return dispatch => {
leagueFireDB.path = `users/`;
leagueFireDB.subscribeChild(dispatch);
};
}
export function loadLeagueSuccess(league) {
console.log("LEAGUElOADSuccess::", league);
return {
type: types.LOAD_LEAGUE_SUCCESS,
payload: league
};
}
在化简器中,为了将所有深层嵌套的数据正确返回到我从JS使用的连接组件。也许有更好的方法可以做到这一点,但这对我有用。
import { Record, fromJS } from 'immutable';
import {
LOAD_LEAGUE_SUCCESS,
LOAD_LEAGUE_ERROR,
} from '../actions/actionTypes';
export const LeagueState = new Record({
key: null,
value: null
})
export function leagueReducer(state = new LeagueState(), {payload, type}) {
switch (type) {
case LOAD_LEAGUE_SUCCESS:
return state.merge(fromJS(payload));
default:
return state;
}
}
在我的联赛页面(一个连接的组件)中,我在mapstate中连接了一个选择器
const mapStateToProps = (state, ownProps) => {
console.log("MYSTATE::",state)
return {
league: LeagueSelector(state),
}
}
然后在我的选择器中,通过嵌套接受的答案中指定的记录和地图,完成用户数据的整理。
import { createSelector } from 'reselect';
import { Record, Map } from 'immutable';
var ProfileRecord = Record({
profileName: '',
profilePic: '',
teamName: '',
});
var teamRecord = Record({
competitorKey: ''
});
class User extends Record({'profile': new ProfileRecord(), 'team':Map()}) {
constructor({profile, team} = {}) {
super({team: Map(team).map(x=>new teamRecord(x)), profile: new ProfileRecord(profile)})
}
}
export function getLeague(state) {
return state
}
export function getLeagueList(state) {
return Map(state.league.value).map(x=>new User(x));
}
//=====================================
// MEMOIZED SELECTORS
//-------------------------------------
export const LeagueSelector = createSelector(
getLeague,
getLeagueList,
);
这是我们整齐地嵌套的不变混乱的最终证明。 :)