一.常用脚手架工具react-create-app
二.常规组件架构
import React,{Component} from 'react'
class HelloWorld extends Component {
constructor() {
super()
this.state = {}
}
render() {
return <div></div>
}
}
export default HelloWorld
三.数据单向绑定及改变state状态中的数据
<p>{this.state.msg}</p>
1.this.setState({
属性名: 新的值
})
2.this.setState( prevState => ({
属性名:function(prevState.属性名){...}
}) )
四.事件绑定
1.<input type="text" ref="ipt" value={this.state.ipt} onChange={ () => this.clickIpt()}></input>
clickIpt() {
const newVal = this.refs.ipt.value
this.setState({
ipt: newVal
})
}
2.其他方式详见react文档,
五.props的第三方包prop-types的使用,以及props值改变之后对应组件钩子函数接收问题
import propTypes from 'prop-types'; //props属性的类型校验
class ClickObj extends Component {
static propTypes = {
countobj: propTypes.number.isRequired //属性类型范围为number,必须由父组件给出props值
}
static defaultProps = {//默认不传props时的值
countobj: 100
}
}
当父组件的传值props值改变时,可以在子组件的钩子函数componentWillReceiveProps中接受到,并结合setState改变子组件的state
componentWillReceiveProps(nextProps) {
console.log(nextProps.countobj)
this.setState({
count: nextProps.countobj
})
}
六.两种定义组件的方式=>(匿名函数式,class类定义式)
1.匿名函数式,不具备state等,不具备生命周期创建,只返回对应的模板结构
function List(props) {
return <li className={listStyle.item}>
<h1>{props.name}</h1>
<p>{props.age}</p>
</li>
2.class类定义式 => 具备完整的生命周期,state,props等,可以用作复杂的组件构建,较常用
七.自定义样式的模块化配置及使用,以及第三方样式框架的使用
1.在react-create-app项目中用npm run eject自动生成配置文件,在Webpack配置文件中修改为如下:
//在one of里添加
{
test: /\.(less)$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
modules: true,//开启css 模块化
localIdentName: '[path][name]__[local]--[hash:base64:5]',//配置生成的标识符(ident)
importLoaders: 2,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
require.resolve('less-loader')
],
},
2.导入类样式对象,并且在jsx代码里直接用属性绑定的方式赋值给className或id
import listStyle from '@/list.less'
//className绑定类名
<li className={listStyle.item}>
<h1>{props.name}</h1>
<p>{props.age}</p>
</li>
//id绑定id值
<ul id={listStyle.list}></ul>
3.第三方import导入第三方样式对象,并进行属性绑定
八.循环数据生成模板
<ul id={listStyle.list}>
{this.state.list.map(item => <List {...item} key={item.id}></List>)} //数组的map方法返回一个经处理后的新数组,循环生成的每一个子项需绑定唯一key值
</ul>
九.声明周期
初始化
1.static ***
2.constructor(props) {...} ,创建state
3.componentWillMount,类似Vue的created,数据已创建好,可进行ajax进行动态数据改变
4.render,数据向模板渲染阶段
5.componentDidMount,虚拟dom树已经建立,可以进行DOM操作
进行中
6.props改变,调用componentWillReceiveProps,接受新的props,可进行动态state改变
7.state改变时,调用shouldComponentUpdate(nextProps,nextState),可进行对状态改变的选择性处理,return true时允许状态改变,否则不允许
8.状态即将改变前,componentWillUpdate
9.状态改变完成,componentDidUpdate
10.组件卸载,componentWillUnmount
*** 能调用setState的生命周期函数 => componentWillMount,componentDidMount,componentWillReceiveProps
十.父子组件互相传值
1.子组件 => 父组件
1.1父组件声明处理函数
comment(obj) {
console.log(obj)
}
1.2父组件给子组件绑定属性props
<CmtBox comment={ this.comment.bind(this) } ></CmtBox>
1.3子组件通过props调用该函数并传本组件的数据
const cmtObj = {
id: Date.now(),
user,
cmt
}
this.props.comment(cmtObj)
2.父组件向子组件传值,绑定到子组件的props上