(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"));