layout组件
2019-11-13 本文已影响0人
sweetBoy_9126
- layout.example.tsx
import React from 'react'
import Layout from './layout'
import Header from './header'
import Content from './content'
import Footer from './footer'
const LayoutExample: React.FunctionComponent = () => {
return (
<div>
<h1>第一个例子</h1>
<Layout style={{height: 500}}>
<Header>header</Header>
<Content>content</Content>
<Footer>footer</Footer>
</Layout>
</div>
)
}
export default LayoutExample;
上面我们直接在Layout上写style或者className的话,就会报错说我们没有声明对应的参数,这时候我们就需要在Layout里声明一下
- Layout.tsx
// 让props继承React.HTMLAttributes
interface Props extends React.HTMLAttributes<HTMLElement>{
}
const Layout: React.FunctionComponent<Props> = (props) => {
const {className, ...rest} = props
return (
<div className={classNames(sc(), className)} {...rest}>
{props.children}
</div>
)
}
在layout中使用Aside
通过遍历拿到它的children,判断它里面的每一项的type是否等于Aside来添加一个类
const Layout: React.FunctionComponent<Props> = (props) => {
const {className, ...rest} = props
let hasAside = false
if ((props.children as Array<ReactElement>).length) {
(props.children as Array<ReactElement>).map(node => {
if (node.type === Aside) {
hasAside = true
}
})
}
return (
<div className={classNames(sc(), className, hasAside ? 'hasAside' : '')} {...rest}>
{props.children}
</div>
)
}
对上面的代码进行优化,因为函数式不能进行二次赋值,所以我们要想办法把let去掉,数组里只要有一个是true就返回true,我们可以用reduce
(props.children as Array<ReactElement>).reduce((result, node) => result || node.type === Aside, false)
将初始值定为false,返回上一个每次结束后的值或当前值,只要是true就会返回
const Layout: React.FunctionComponent<Props> = (props) => {
const {className, ...rest} = props
const children = props.children as Array<ReactElement>
const hasAside = children.length
&& children.reduce((result, node) => result || node.type === Aside, false)
return (
<div className={classNames(sc(), className, hasAside ? 'hasAside' : '')} {...rest}>
{props.children}
</div>
)
}