记录一下自己平时使用react用到的地方
官方脚手架
yarn eject
暴露配置文件- webpack.config.js alias
使用less、less module
按需引入antd
修改antd默认主题、less变量
函数组件跟类组件的定义、props的使用
// 定义函数组件
export default function (props) {
// 渲染props值为字符串
return (
<div>{props.title}</div>
)
}
// 定义类组件
export default class Title extends React.Component {
render() {
return (
<div>
{this.props.title}
</div>
)
}
}
// 导入组件
import Title from './Title';
// 使用该组件(在另一个组件中)
export default function () {
// 渲染props值为字符串
return (
<Title title='title' />
)
}
组件的生命周期、组件状态
import React from 'react';
export default class Title extends React.Component {
constructor(props) {
super(props);
this.state = {
date: (new Date()).toLocaleTimeString(),
}
}
// 组件挂载到DOM上时自动执行
componentDidMount() {
this.timer = setInterval(() => {
this.setState({
date: (new Date()).toLocaleTimeString(),
}, () => {
// 状态更新是异步操作,所以当需要获取新的状态值时需传入将会在状态更新后异步执行的函数
console.log(this.state.date);
})
}, 1000);
}
// 组件从DOM树上卸载时执行
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return (
<div>
{this.state.date}
</div>
)
}
}
事件处理、传参、state hook、条件渲染
import React, { useState } from 'react';
export default function () {
const [status, setStatus] = useState(false);
function handleClick() {
setStatus(!status);
}
function handleChange(status) {
setStatus(status)
}
return (
<>
<div>
{status && <span>true</span>}
</div>
<button onClick={handleClick}>{status ? 'close light' : 'open light'}</button>
<br />
<button onClick={() => { handleChange(!status); }}>{status ? 'close' : 'open'}</button>
</>
)
}
children
import React from 'react';
export default function ({ children }) {
return (
<div>{children}</div>
)
}
// 使用
<Title>
hello
</Title>
static propTypes、defaultProps、循环渲染
import React from 'react';
export default class Title extends React.Component {
render() {
return (
<ul>
{
this.props.list.map(item => (
<li key={item.id}>{item.name}</li>
))
}
</ul>
)
}
}
Title.defaultProps = {
list: []
}
Title.propTypes = {
list: PropTypes.array,
}
受控组件
默认的表单输入元素都是非受控组件,自己来维护状态,可以将状态指向组件状态通过组件来控制
import React, { useState } from 'react';
export default function () {
const [name, setName] = useState('some value')
function handleChange(e) {
setName(e.target.value)
}
return (
<input value={name} onChange={handleChange} type="text" />
)
}
状态提升:将状态提升至父组件,子组件渲染、调用父组件方法来修改
// 父组件
import React from 'react';
import React, { useState } from 'react';
import Title from './Title'
export default () => {
const [name, setName] = useState('');
return (
<div>
<div>{name}</div>
<Title name={name} handleChange={setName} />
</div>
)
}
// 子组件
import React from 'react';
export default function (props) {
function onChange(e) {
props.handleChange(e.target.value);
}
return (
<div>
<input value={props.name} onChange={onChange} type="text" />
</div>
)
}
动态样式(className, style)
import React, { useState } from 'react';
import Title from './Title'
export default () => {
const [blue, setBlue] = useState(false);
return (
<div className={`red ${blue ? 'blue' : ''}`} style={{ color: `${blue ? 'blue' : 'red'}` }}>
<div onClick={() => { setBlue(!blue) }}>click</div>
</div>
)
}
代码分割(页面级别)
使用React.lazy(() => import('./component'))
导入页面组件,配合react-router-dom
做路由,<Suspense fallback={}>
在等待加载组件时做降级处理,再定义一个异常捕获边界(Error boundaries)用来捕获模块加载失败问题(如网络问题,服务器关闭),不支持服务端渲染
context
获取DOM节点(常用来给第三方DOM库使用,如图表库)
import React from 'react';
export default class Title extends React.Component {
componentDidMount() {
console.log(this.instance)
}
render() {
return (
<div ref={e => this.instance = e}></div>
)
}
}
Fragments(DOM树中没有该元素)
return (
<>
<span>hello,</span>
<span>world</span>
</>
)
import React, { Fragment } from 'react';
export default function (props) {
return (
<Fragment>
<span>hello,</span>
<span>world</span>
</Fragment>
)
}