Javascript 子页面不';不匹配路由器4
我的路由器是这样设置的Javascript 子页面不';不匹配路由器4,javascript,node.js,reactjs,react-router,react-router-dom,Javascript,Node.js,Reactjs,React Router,React Router Dom,我的路由器是这样设置的 <Switch> <PrivatePage key={index} {...opts} component={(props) => <Section {...props} pages={childRoutes} /> } /> <PrivatePage path='/accounts/:id' exact={true} render={({ match }) => ( <Redi
<Switch>
<PrivatePage key={index} {...opts} component={(props) =>
<Section {...props} pages={childRoutes} />
} />
<PrivatePage path='/accounts/:id' exact={true} render={({ match }) => (
<Redirect to={/accounts/${match.params.id}/profile} />
)} />
...
<Route component={NotFound} />
</Switch>
的渲染方法(由
render(){
常数{
activeClass,
集装箱班,
exactLink,
气垫舱,
偶像
标签,
链接
onClick,
手工的,
}=这是道具
让消息=(
{label}
)
如果(图标){
消息=(
{label}
)
}
const buttonContainerClass=this.isHovering()?`${containerClass}${hoverClass}`:containerClass
常量按钮容器=道具=>(
this.handleMouseIn()}
onMouseLeave={()=>this.handleMouseOut()}
>
{message}
)
让结果
如果(链接的类型)=“字符串”){
if(typeof(activeClass)='string'&&activeClass.length>0){
常量选项={
activeClassName:activeClass | |“”,
类名:buttonContainerClass | |“”,
精确:exactLink | | false,
isActive:handleActive | |未定义,
严格:是的,
致:link,,
}
结果=(
)
}否则{
结果=(
)
}
}else if(typeof(onClick)==“函数”){
结果=(
onClick()}/>
)
}否则{
console.warn('按钮必须有一个动作props>,{props:this.props})
}
返回结果
}
我遇到了一个类似的问题,交换机没有找到用其他组件包装的路由。从源代码看,似乎Switch
没有递归地在子项中查找Route
s,因此它们不能嵌套
在这种情况下,要使用Switch
,您需要重构以使Route
成为每个路由的顶级组件。或者重构以不使用Switch
——使所有路由基本上精确匹配
开关源:
它使用
React.Children.forEach
查找路径,该路径只迭代直接子级,而不是嵌套子级。我遇到了一个类似的问题,Switch没有找到用其他组件包装的路由。查看源代码,看起来Switch
没有在子级r中查找Route
s因此,它们不能嵌套
在这种情况下,要使用Switch
,您需要重构以使Route
成为每个路由的顶级组件。或者重构以不使用Switch
——使所有路由基本上精确匹配
开关源:
它使用
React.Children.forEach
查找路径,该路径只迭代直接子对象,而不是嵌套子对象。如何进入仪表板?通过Link
?可以显示该片段吗?更新了@Panther,我使用的是您的一些代码中有一些错误,例如路径中的道具有一个组件道具s拼错了,您的路线周围需要引号@Falieson@Win如果我说错了什么,我肯定typescript会抓住的。也许我在这篇文章中说错了,你能帮我找到你在引用什么吗?你怎么去仪表板?通过链接?你能展示那篇文章吗?更新了@Panther,我正在使用你在som中有一些错误代码的一部分,例如路线中的道具,有一个组件道具拼错了,路线周围需要引号@Falieson@Win如果我说错了什么,我相信typescript会抓住的。也许我在这篇文章中说错了,你能帮我找到你引用的东西吗?我怀疑这可能是问题所在,谢谢你-我会尽力确认的;然后接受等。再次感谢。我发现路由的容器是exact={false}(notfound页面除外),然后其他所有内容都需要exact={true}我想?我怀疑这可能是问题所在,谢谢-我会尝试确认,然后接受等等。再次感谢。我发现路由的容器是exact={false}(除了notfound页面),然后所有其他内容都需要exact={true}并且开关工作。我想?
<SubNavMenu />
<Route path=/accounts/:id/profile componet={ProfilePage} />
<Route path=/accounts/:id/dashboard componet={DashboardPage} />
const PrivatePage = ({ component: Component, ...rest }) => {
let result = props => (
<Redirect
to={{
pathname: '/redirect',
state: { from: props.location },
}}
/>
)
if (User.methods.isAuthed()) {
result = props => (
<Page>
<Component {...props} />
</Page>
)
} else if (rest.path === '/') {
result = props => (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
return <Route {...rest} render={props => result(props)} />
}
export default PrivatePage
pages = [
{
authed: true,
icon: 'cog',
component: (<div/>),
name: 'AccountDetailSection',
path: `/accounts/:id/profile`,
},
{
authed: true,
component: AccountProfilePage,
exact: true,
getLink: id => `/accounts/${id}/profile`,
icon: 'cog',
label: 'Account',
name: 'AccountDetailProfile',
parent: 'AccountDetailSection',
path: `/accounts/:id/profile`,
},
{
authed: true,
component: AccountDashboardsPage,
exact: true,
getLink: id => `/accounts/${id}/dashboard`,
icon: 'cog',
label: 'Dashboard',
name: 'AccountDetailDashboards',
parent: 'AccountDetailSection',
path: `/accounts/:id/dashboard`,
},
]
class PrivateSection extends React.Component<IProps, IState> {
classes = { // static values
button: 'App-navigation--listItemButton',
container: 'App-navigation',
header: 'App-navigation--header',
headerLogo: 'App-navigation--headerLogo',
listContainer: 'App-navigation--list',
listItem: 'App-navigation--listItem',
listItemActive: 'App-subnavigation--listItem--active',
listItemHover: 'App-navigation--listItem--hover',
positionBottom: 'App-navigation--bottom',
positionTop: 'App-navigation--top',
}
sharedProps = { // static values
activeClass: this.classes.listItemActive,
buttonClass: this.classes.button,
buttonContainer: this.classes.listItem,
hoverClass: this.classes.listItemHover,
menuContainer: this.classes.listContainer,
onHover: this.handleMouseIn.bind(this),
}
constructor(props: IProps) {
super(props)
this.state = {
hovering: '',
}
}
handleMouseIn(name: string) {
this.setState({hovering: name})
}
handleMouseOut() {
this.setState({hovering: ''})
}
renderSubNav() {
const navOpts = {
hovering: this.state && this.state.hovering || '',
onHover: this.handleMouseIn.bind(this),
}
const navItems: any = this.props.pages.map(p => { // tslint:disable-line no-any
const o = {...p}
if (typeof(o.getLink) === 'function') {
const {id} = this.props.match && this.props.match.params || {id: ''}
o.link = o.getLink(id)
o.getLink = undefined
}
o.authed = undefined
o.exact = undefined
o.component = undefined
return {...navOpts, ...o}
})
const submenuClasses = {
active: this.sharedProps.activeClass,
button: this.sharedProps.buttonClass,
buttonContainer: this.sharedProps.buttonContainer,
hover: this.sharedProps.hoverClass,
menuContainer: this.sharedProps.menuContainer,
}
return (
<div
className='profile_subnav'
style={{height: '100%'}}
onMouseLeave={() => this.handleMouseOut()}
>
<Menu
items={navItems}
classes={submenuClasses}
/>
</div>
)
}
renderContent() {
return (
<div className='profile_content'>
{this.props.pages.map((opts, index) => {
const o: any = {...opts} // tslint:disable-line no-any
if (typeof(o.getLink) === 'function') {
const {id} = this.props.match && this.props.match.params || {id: ''}
o.link = o.getLink(id)
o.getLink = undefined
}
return (
<PrivateRoute key={index} {...o}/>
)
})}
</div>
)
}
render() {
return (
<div
className='page--content_container'
>
{this.renderSubNav()}
{this.renderContent()}
</div>
)
}
}
export default PrivateSection
render() {
const {
activeClass,
containerClass,
exactLink,
hoverClass,
icon,
label,
link,
onClick,
handleActive,
} = this.props
let message = (
<div className='Button--message'>
<div className='Button--messageText'>{label}</div>
</div>
)
if (icon) {
message = (
<div className='Button--message'>
<div className='Button--messageIcon'><Icon name={icon} / ></div>
<div className='Button--messageText'>{label}</div>
</div>
)
}
const buttonContainerClass = this.isHovering() ? `${containerClass} ${hoverClass}` : containerClass
const ButtonContainer = props => (
<button
{...props}
className={this.props.buttonClass || ''}
onMouseEnter={() => this.handleMouseIn()}
onMouseLeave={() => this.handleMouseOut()}
>
{message}
</button>
)
let Result
if (typeof(link) === 'string') {
if (typeof(activeClass) === 'string' && activeClass.length > 0) {
const opts = {
activeClassName: activeClass || '',
className: buttonContainerClass || '',
exact: exactLink || false,
isActive: handleActive || undefined,
strict: true,
to: link,
}
Result = (
<NavLink {...opts} >
<ButtonContainer />
</NavLink>
)
} else {
Result = (
<Link to={link} className={buttonContainerClass}>
<ButtonContainer />
</Link>
)
}
} else if (typeof(onClick) === 'function') {
Result = (
<div className={buttonContainerClass}>
<ButtonContainer onClick={() => onClick()} />
</div>
)
} else {
console.warn('Button must have an action props> ', {props: this.props})
}
return Result
}