我试图了解在使用 React Router 时看到的特定警告背后的细微差别。我试图根据用户是否登录来设置条件路由。我的代码如下:
\n// AppRoutes.js\nexport\xc2\xa0const\xc2\xa0AppRoutes\xc2\xa0=\xc2\xa0({\xc2\xa0machine\xc2\xa0})\xc2\xa0=>\xc2\xa0{\n\xc2\xa0\xc2\xa0const\xc2\xa0[state]\xc2\xa0=\xc2\xa0useMachine(machine);\n \n let\xc2\xa0routes;\n \n\xc2\xa0\xc2\xa0if\xc2\xa0(state.matches(\'authenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0exact\xc2\xa0path="/"><HomePage\xc2\xa0/></Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/contacts"><ContactsList\xc2\xa0/></Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0if\xc2\xa0(state.matches(\'unauthenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<LoginPage\xc2\xa0service={state.children.loginMachine}\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0null;\n\xc2\xa0\xc2\xa0}\n \n\xc2\xa0\xc2\xa0return\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<BrowserRouter>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Switch>{routes}</Switch>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</BrowserRouter>\n\xc2\xa0\xc2\xa0);\n};\nRun Code Online (Sandbox Code Playgroud)\n在内部,HomePage 组件重定向到/contacts
// HomePage.js\nexport const HomePage = () => {\n return <Redirect to="/contacts" />;\n};\nRun Code Online (Sandbox Code Playgroud)\n现在,使用此代码,应用程序可以按照我的需要运行,但我在控制台中记录了一条警告:
\nWarning: <Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.\nRun Code Online (Sandbox Code Playgroud)\n我做了一些研究,我唯一能找到的是这个/sf/answers/3677845041/,这似乎表明有条件地渲染路由导致了问题。然而,路由的条件渲染才是重点——我不希望未经身份验证的用户访问/contacts
经过一番尝试后,我将源代码修改如下:
\n// AppRoutes.js\nexport\xc2\xa0const\xc2\xa0AppRoutes\xc2\xa0=\xc2\xa0({\xc2\xa0machine\xc2\xa0})\xc2\xa0=>\xc2\xa0{\n\xc2\xa0\xc2\xa0const\xc2\xa0[state]\xc2\xa0=\xc2\xa0useMachine(machine);\n \n\xc2\xa0\xc2\xa0let\xc2\xa0routes;\n \n\xc2\xa0\xc2\xa0if\xc2\xa0(state.matches(\'authenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/home">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<HomePage\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/contacts">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<ContactsList\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Redirect\xc2\xa0to="/home"\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\xc2\xa0else\xc2\xa0if\xc2\xa0(state.matches(\'unauthenticated\'))\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0routes\xc2\xa0=\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Route\xc2\xa0path="/login">\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<LoginPage\xc2\xa0service={state.children.loginMachine}\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</Route>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Redirect\xc2\xa0to="/login"\xc2\xa0/>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</React.Fragment>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0);\n\xc2\xa0\xc2\xa0}\n \n\xc2\xa0\xc2\xa0return\xc2\xa0(\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<BrowserRouter>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0<Switch>{routes}</Switch>\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0</BrowserRouter>\n\xc2\xa0\xc2\xa0);\n};\n\n// HomePage.js\nexport const HomePage = () => {\n return <Redirect to="/contacts" …Run Code Online (Sandbox Code Playgroud) 我有一个需要在Angular应用程序中对两个@Ngrx操作进行排序的场景。
第一个动作使用一些数据更新状态,第二个动作使用该数据触发服务器调用。我正在使用效果对这两个动作进行排序,并仅在第一个动作完成后才触发第二个动作。
为了确保第二个动作包括来自状态的最近更新的数据,我将存储注入到我的效果中,并使用选择器函数检索数据并将其作为第二个动作的有效负载包括在内。
这可行。
我的问题
但是,我相信,由于this.actions$已经是可观察的流,因此我应该能够简单地转换该流上的每个事件并将其转换为不同的动作。
我所想到的粗略的大理石图:

我正在使用withLatestFrom运算符将操作流与状态数据组合在一起。
@Effect()
lazyEffect1$ = this.actions$.ofType(LazyActions.TEST_ACTION_SEQUENCE)
.withLatestFrom(this.filterId$, (x, y) => {
return new LazyActionDone(y.number);
});
Run Code Online (Sandbox Code Playgroud)
但是这段代码给了我一个错误:
TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
我已经能够使用稍微不同的结构来使其工作,下面的代码中也包含该结构。
但我想了解为什么lazyEffect1不能正常工作。我的理解力在哪里使我失望?
代码
NgRx还原剂:
// reducers.ts
export function lazyReducer(
state: any = {},
action: LazyAction | LazyActionDone
) {
switch (action.type) {
case LazyActions.TEST_ACTION_SEQUENCE: {
console.info('Action Received in Reducer: ', action.type);
return {
...state, …Run Code Online (Sandbox Code Playgroud) 我试图使用RxJS groupBy运算符,然后concatMap根据一些键将记录收集到单独的组中。
我注意到,当concatMap跟随groupBy运算符时,似乎会丢失第一个键之后出现的所有键的数据。
例如:
考虑以下代码块:
// DOES NOT WORK
const records = ['a:1', 'b:2', 'c:3', 'd:1', 'e:2', 'f:3', 'g:1'];
const clicks = new Subject();
const result = clicks.pipe(
groupBy(x => x.substr(2,1)),
concatMap(ev$ => ev$.pipe(map(x => ({key: ev$.key, value: x})))),
);
const subscription = result.subscribe(x => console.log(x));
records.forEach(x => clicks.next(x));
// Expected Output:
// { key: '1', value: 'a:1' }
// { key: '1', value: 'd:1' }
// { key: '1', value: 'g:1' } …Run Code Online (Sandbox Code Playgroud)