我正在尝试使用React 16.3中的新上下文API对我的应用程序进行一些测试,但我无法理解为什么我的重定向永远不会起作用。
<ContextA>
<Switch>
<Route exact path='/route1' component={ Component1 } />
<ContextB>
<Route exact path='/route2' component={ Component2 } />
<Route exact path='/route3' component={ Component3 } />
</ContextB>
<Redirect from='/' to='/route1' />
</Switch>
</ContextA>
我不希望我的ContextB可用于所有路由,只有2和3.我该怎么做?
答案 0 :(得分:9)
警告他人,接受的答案并非真正有效,正如您对原始(无效)概念所期望的那样:
// This comes from the original question (doesn't work as-is!)
<ContextA>
<Switch>
<Route exact path='/route1' component={ Component1 } />
<ContextB>
<Route exact path='/route2' component={ Component2 } />
<Route exact path='/route3' component={ Component3 } />
</ContextB>
<Redirect from='/' to='/route1' />
</Switch>
</ContextA>
在这里,/route2
和/route3
正在共享上下文,期望应该是:
Component2
或Component3
更新了上下文,则更改应反映回对方。以上都不是公认的解决方案。
答案 1 :(得分:6)
看起来<Switch>
应该只有<Route>
和<Redirect >
组件作为直接子项。 (source)
我认为这就是为什么Redirect
无效,因为您使用ContextB
作为Switch
孩子。
最简单但重复的解决方案可能是将ContextB
作为您想要的每个<Route>
的孩子传递:
注意:这些解决方案假设您为此分配了Context组件的默认值,如下所示:
const MyContext = React.createContext(defaultValue);
<Route exact path='/route2'>
<ContextB.Provider>
<Component1 />
</ContextB.Provider>
</Route>
您甚至可以为此创建ContextRoute
组件:
import React from 'react';
import { Route } from 'react-router-dom';
const ContextRoute = ({ contextComponent, component, ...rest }) => {
const { Provider } = contextComponent;
const Component = component;
return (
<Route {...rest}>
<Provider>
<Component />
</Provider>
</Route>
);
};
export default ContextRoute;
然后将其用作路线:
<ContextA>
<Switch>
<Route exact path='/route1' component={ Component1 } />
<ContextRoute exact path='/route2' contextComponent={ContextB} component={ Component2 } />
<ContextRoute exact path='/route3' contextComponent={ContextB} component={ Component3 } />
<Redirect from='/' to='/route1' />
</Switch>
</ContextA>
使用此解决方案,您可以在嵌套的组件中使用渲染道具的上下文:
return (
<ContextB.Consumer>
{value => <div>{value}</div>}
</ContextB.Consumer>
);
但我们可以想象更多的解决方案,比如 HOC ,将上下文值直接传递给路径组件道具等......
答案 2 :(得分:1)
感谢您的帮助,我在商店环境中使用了它,并且可以使用! (createContext和useReducer)
import React, {createContext, useReducer} from "react";
import Reducer from './reducer.js'
const initialState = {
/* */
};
const Store = ({children}) => {
const [state, dispatch] = useReducer(Reducer, initialState);
return (
<Context.Provider value={[state, dispatch]}>
{children}
</Context.Provider>
)
};
export const Context = createContext(initialState);
export default Store;
/ *在App.js * /
中const App = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" render={ (props)=> <Store> <Home {...props} /> </Store> } />
<Route exact path="/about" render={ (props)=> <Store> <About {...props} /> </Store> } />
<Route exact path="/login" render={ (props)=> <Store> <Login {...props} /> </Store> } />
</Switch>
</BrowserRouter>
);
};
答案 3 :(得分:0)
在Route中使用render方法。这将解决您的问题,就像我在应用程序中所做的一样。
<Route path="/" render={ (props)=> <ContextB> <Component2 {...props} /> </ContextB> }
答案 4 :(得分:0)
简单的解决方案:
Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2````