1. setState() 的两种用法
react 作为“数据驱动视图变化”的MVVM框架,setState 是我们更改组件内state的唯一方法。我们一般使用传给setState() 一个对象的方式,其实setState()还可以接受函数修改state,而且两者的一些使用区别很有可能是我们忽视的。
1. setState() 传入对象参数
this.state = {
name: 'wuyanbin',
age: '24'
}
this.setState({
name: 'wahaha'
})
2. setState() 传入函数参数
this.state = {
name: 'wuyanbin',
age: '24'
}
this.setState((preState, props)=>{
console.log('在此可以打印出上一次的state和传入的props');
return {name: 'wahaha'}
})
setState 方法是子组件继承父component, 当我们调用该方法的时候,react会更改state, reader方法会根据最新的状态渲染页面。值得注意的是,setState方法并不是同步执行的,而是异步执行。当我们调用setState,react并不会马上执行,而是将修改的对象放到一个消息队列中,稍后才会执行修改,并执行render方法渲染。
由于 setState() 的异步性,所以他还可以接受一个回调函数。传入函数参数同理。
this.setState({
name: 'hahaha'
},()=>{
console.log('在此执行回调');
})
SetState 是同步的还是异步的
https://juejin.im/post/6844903636749778958#heading-7
2. Props
组件化增加了组件之间通信的成本,react 提供的props 主要就是用于父组件向子组件传递一些配置信息,用于控制子组件的显示和动作。(context 不被推荐使用)
1.defaultProps
有时候我们可以在子组件提供一个默认值,避免父组件忘记传值导致的bug.
state defaultProps = {
name: '我是默认值'
}
2. propTypes类型检查
js 的弱类型导致了他在构建大型应用程序面前略显逊色,业界出现的typeScript 和 flow 也是为了弥补这个缺陷。react.js 提供了一套组件参数类型规则,让开发者能够趁早发现因为类型不符合规则导致的问题。
1. 安装propTypes
npm install --save propTypes
2. 两种写法
在组件类外:
// 类型检查
xxx(组件名称).propTypes = {
name: propTypes.string.isRequired,
age: propTypes.number
}
// 默认值
xxx(组件名称).defaultProps = {
name: 'wuyanbin',
age: '12'
}
在组件类中:(这个语法还没有最终通过,在浏览器中需要一步编译工作。)
static defaultProps = {
name: 'wuyanbin'
}
static propTypes = {
name: propTypes.string.isRequired
}
支持的检查类型:
propTypes.string
propTypes.number
propTypes.object
propTypes.array
propTypes.symbol
propTypes.func
propTypes.bool
...
更多 https://react.docschina.org/docs/typechecking-with-proptypes.html#proptypes
3. 高阶组件(HOC: High-Order Component )
高阶组件就是一个函数,把一个组件作为参数传入,返回一个新的组件。
高阶组件的形式:
export default (WrappedComponent,...其他参数)=>{
class NewComponent extends Component{
// 可以自定义一些处理逻辑
render(){
return (
<WrappedComponent/>
)
}
}
return NewComponent;
}
使用形式:
const outputComponent = highOrderComponent(inputComponent,...其他参数)
高阶组件使用的场景:
当有多个组件需要相同的处理逻辑,我们可以把这部分逻辑提取到高阶组件中,可以保证代码的复用性和简洁性;后期如果有逻辑需要修改,统一修改高阶组件中的逻辑,极大的增加了代码的可维护性。
4. react代码编写规范
所谓的代码规范其实没有什么优劣之分,就像各个国家、各个地区的法律法规,各有差异,但最主要的是能够起到约束和规范的作用。团队形成一个代码规范,能够减少个人代码编写习惯导致团队其他成员理解的成本,降低项目维护难度。
1. 编写组件的规范
编写一个react组件的时候,我们可以按照以下的方式顺序进行。
static 开头的类属性,如
defaultProps
、propTypes
。构造函数,
constructor
。组件生命周期。
_
开头的私有方法。事件监听方法,
handle*
。render*
开头的方法,有时候render()
方法里面的内容会分开到不同函数里面进行,这些函数都以render*
开头。render()
方法。
class ReactStandard extends Component {
// static 开头的静态属性
static defaultProps = {
name: 'wuyanbin',
age: 24
};
static propTypes = {
name: propTypes.string.isRequired,
age: propTypes.number.isRequired
};
// 构造函数
constructor(props) {
super(props);
this.state = {
name: 'wahaha',
age: 24
};
this.handleInputChange = this.handleInputChange.bind(this)
}
// 组件的生命周期
componentWillMount() {
}
componentDidMount() {
this._fetchAsyncData()
}
// _开头的私有方法
_fetchAsyncData = () => {
console.log('加载数据');
};
// 事件监听 handle*
handleInputChange(event) {
console.log(event.target.value);
this.setState({
name: event.target.value
})
};
// render*
renderTitle = () => {
return <div>this is Title</div>
};
renderFooter = () => {
return <div>this is Footer</div>
};
// render() 方法
render() {
return (
<div>
{this.renderTitle()}
<div>
<input
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</div>
{this.renderFooter()}
</div>
);
}
}
2. 目录结构及文件命名规范
待整理,先提出一版,与大家讨论下形成一个公认的版本
5. redux
- dispatch: 修改redux 中state 的中间人。
- createStore(): 一个生产
- reducer(state, action){ }: 初始化state 和 根据action 的type修改指定的state
6. react-redux
- connect(): 高阶组件,将公共的逻辑封装到组件中。从store中取出数据通过props传给WrappedComponent 形式如下:
connect(mapStateToProps,mapDispatchToProps)(WrappedComponent)
mapStateToProps: 告诉高阶组件connect 当前的 组件需要从store取出什么数据
mapDispatchToProps: 告诉高阶组件connect 当前的 组件需要从store 执行什么dispatch 操作
- Provider: 容器组件