项目结构是这样:
程序是做一个登录功能的demo,WithLoginComponent是个封装的函数组件,用来包装登录功能,用户在login组件登录后状态会通过contex的方式更新到WithLoginComponent和userbar组件,searcbar组件会显示一个注销按钮。
碰到的问题是userbar组件可以usecontext获取到state,但是WithLoginComponent不行。
项目结构
const TableWithDataSource = withDataSource(FareTable)
export default function App(props) {
const [state, dispatch] = useReducer(loginReducer, initialState);
const [searchCons,setSearchCons]=useState({"dCity":"sha","aCity":"bkk"})
var con =getLocationCon();
if(con!=null){
}
const search=(dCity,aCity)=>{
let newcons ={searchCons: {dCity:dCity,aCity:aCity}};
setSearchCons(newcons)
}
return(
<div>
<UserContext.Provider value={{state, dispatch}}>
<Router>
<NavLinkHeader></NavLinkHeader>
<Route exact name="登录" path="/login" component={Login} />
<Route exact name="首页" path="/" component= {WithLoginComponent(Home,state)} />
<Route exact name="首页2" path="/home2" component={WithLoginComponent(Home2,state)} />
<Route path="/list" render={() => (
<Route name="列表页" path="/list"
render={(props) => (
<div>
<SearchBar search={ search} searchCons={ searchCons}/>
<TableWithDataSource search={ search} searchCons={ searchCons} />
</div>
)}/>
)}/>
</Router>
</UserContext.Provider>
</div>
)
}
;
userbar组件在SearchBar里面。
<div style={{float:"left"}}>
<NavLink className="menu-link" activeClassName="active2" activeStyle={{color: '#fff'}} exact to="/" >首页</NavLink>
<NavLink className="menu-link" activeClassName="active2" activeStyle={{color: '#fff'}} exact to="/home2" >首页2</NavLink>
<NavLink className="menu-link" activeClassName="active2" to="/list" >运价列表</NavLink>
<NavLink className="menu-link" activeClassName="active2" to="/us" >关于我们</NavLink>
</div>
<div style={{ clear:"right",height:30,float:"right", backgroundColor:"black", margin:0}}>
<UserBar />
</div>
<div style={{clear:"both"}} />
</div>
WithLoginComponent和userbar都是通过usercontext获取state
userbar代码
const { dispatch, state } = useContext(UserContext);
let logoutClick=()=>{
logout()
dispatch({type:"logout"})
props.history.push("/");
}
if(state.login){
return (
<div>
<a onClick={(e)=>{e.preventDefault();logoutClick() } }> 注销登录</a>
</div>)
}
else{
return null
}
}
export default withRouter(UserBar)
WithLoginComponent
function WithLoginComponent(Component){
const { dispatch, state } = useContext(UserContext);
return (props)=>{
if(!state.login){
props.history.push("/login")
return null
}
return <Component />
}
}
export default WithLoginComponent
这两个组件的层级不同,WithLoginComponent和<UserContext.Provider value={{state, dispatch}}> 在同一个目录,网上有说可能会出现UserContext初始化后马上使用获取不到值的情况,但是没说怎么解决。
同时我修改代码发现在WithLoginComponent里直接获取context是可以成功。
function WithLoginComponent(Component,context){
//const { dispatch, state } = useContext(UserContext);
return (props)=>{
if(!context.login){
props.history.push("/login")
return null
}
return <Component />
}
}
export default WithLoginComponent
页面和userbar状态都成功改变
虽然可以实现功能,但是不知道原因,usecontext源代码太难懂了~~