layout组件

2019-11-13  本文已影响0人  sweetBoy_9126
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里声明一下

// 让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>
  )
}
上一篇下一篇

猜你喜欢

热点阅读