React复习(7)

(1)fragment

我们直接使用组件时会因为报警告,因为<td>标签不能作为<div>的子节点出现
所以我们利用fragment来解决这个问题
class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Column />
        </tr>
      </table>
    )
  }
}
//会报错
function Column (){
    return (
        <div>
            <td>hello</td>
            <td>world</td>
        </div>
    )
}
//Fragment给子元素分组,不需要像子元素添加额外的DOM节点
//也会报警告,但是并不是原则上错误
function Column (){
    return (
        <React.Fragment>
            <td>hello</td>
            <td>world</td>
        </React.Fragment>
    )
}
//Fragment短语法,不支持key
function Column (){
    return (
        <>
            <td>hello</td>
            <td>world</td>
        </>
    )
}
ReactDOM.render(<Table />, document.getElementById('app'))

(2)错误边界

当程序出现错误 不应该导致应用崩溃,而是应该先把界面反馈给用户,错误交给程序员处理
错误边界本身是一个组件 能后捕获子组件的错误 ,但是无法捕获自身错误
如果子组件出现错误 则渲染错误边界自定义的错误页面,而不是直接渲染错误或空白
class BugCount extends React.Component {
  state = { count: 0 }
  handleClick = () => {
    console.log('handleClick');
    this.setState(({ count }) => ({ count: count + 1 }))
  }
  render() {
    if (this.state.count === 5) {
      //抛出异常
      throw new Error('count error')
    }
    return <h1 onClick={this.handleClick}>{this.state.count}</h1>
  }
}
class ErrorBoundary extends React.Component {
  //1:声明错误容器
  state = { error: null, errorInfo: null }
  //2:利用钩子函数
  //子组件发生错误异常会被错误边界捕获然后执行componentDidCatch 并传入错误信息
  componentDidCatch(error, errorInfo) {
    console.log('componentDidCatch');
    //3:同步
    this.setState({
      error,
      errorInfo
    })
    console.log(error);
    console.log(errorInfo);
  }
  render() {
    const { error, errorInfo } = this.state
    //4:渲染页面
    //  有错误
    if (error || errorInfo) {
      return (
        <div>
          <h2>Something go Wrong</h2>
          <details style={{ whiteSpace: 'pre-wrap' }}>
            {error && error.toString()}
            <br />
            {errorInfo && errorInfo.componentStack}
          </details>
        </div>
      )
    }
    // 没错误
    return this.props.children
  }
}
function App(){
    return (
        <div>
            <h1>App</h1>
            <ErrorBoundary >
              <BugCount />
            </ErrorBoundary>
        </div>
    )
}
//错误边界包裹 多个子组件,有一个组件crash 错误边界自定义的错误页面 会覆盖所有子组件
function App(){
    return (
        <div>
            <h1>App</h1>
            <ErrorBoundary >
              <BugCount />
              <BugCount />
              <BugCount />
            </ErrorBoundary>
        </div>
    )
}
// 错误边界 各自独立包裹子组件 : 互相不影响 各自提示独立的错误信息
function App() {
  return (
    <div>
      <h1>App</h1>
      <ErrorBoundary >
        <BugCount />
      </ErrorBoundary>
      <ErrorBoundary >
        <BugCount />
      </ErrorBoundary>
      <ErrorBoundary >
        <BugCount />
      </ErrorBoundary>
    </div>
  )
}
ReactDOM.render(<App />, document.getElementById('app'))

(3)发送ajax请求

class App extends React.Component {
  state = {
    repoName: '',
    repoUrl: ''
  }
  render() {
    const { repoName, repoUrl } = this.state
    return (
      <div>
        most stars repo is <a href={repoUrl}>{repoName}</a>
      </div>
    );
  }
  //在这写副作用比较安全
  componentDidMount() {
    //axios方法
    //若没有本地安装axios包,可以使用axios官网的网页版js文件,下载后引入即可
    const url = this.props.url
    axios.get(url).then(resp => {
      console.log(resp);
      let result = resp.data
      let repo = result.items[0]
      let { name, html_url } = repo
      this.setState({
        repoName: name,
        repoUrl: html_url
      })
    })
    //fetch方法
    //本身是promise,用then获取返回值
    //通过json转换成promise,再用then获取
    fetch(url, { method: 'GET' }).then(resp => resp.json()).then(
      data => {
        let repo = data.items[0]
        let { name, html_url } = repo
        this.setState({
          repoName: name,
          repoUrl: html_url
        })
      }
    )
  }
}
const url = 'http://api.github.com/search/repositories?q=vue&sort=stars'
ReactDOM.render(<App url={url} />, document.getElementById("app"));

(4)HOC的基础使用方法

//代码重复率太高,若有很多组件则会有非常多的冗余
class A extends React.Component {
  common() {
    return '组件'
  }
  render() {
    return (
      <div>
        <h1>A component</h1>
        {
          this.common()
        }
      </div>
    )
  }
}
class B extends React.Component {
  common() {
    return '组件'
  }
  render() {
    return (
      <div>
        <h1>B component</h1>
        {
          this.common()
        }
      </div>
    )
  }
}
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>App component</h1>
        <A></A>
        <B></B>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById("app"));
//这时用HOC封装公有的方法或数据
//HOC对现有的组件的增强,进行代码复用,保护原有组件
//先创建一个HOC组件,参数是组件,首字母大写
let HOC = (Component) => {
  return class hocComponent extends React.Component {
    //封装公共的数据
    common = () => {
      return "组件";
    };
    render() {
      //类组件声明之后,通过props来获取值
      return <Component common={this.common} />;
    }
  };
};
class A extends React.Component {
  render() {
    return (
      <div>
        <h1>A component</h1>
        {this.props.common()}
      </div>
    );
  }
}
class B extends React.Component {
  render() {
    return (
      <div>
        <h1>B component</h1>
        {this.props.common()}
      </div>
    );
  }
}
//创建HOC实例,包裹住A和B
let HocA = HOC(A)
let HocB = HOC(B)
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>App component</h1>
        <HocA></HocA>
        <HocB></HocB>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("app"));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无非是我

不必打赏,欢迎指正

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值