声明组件时
首字母必须大写
组件&props
function中有唯一参数 props ->
function App(props){ return <h1> { props.name } </h1> }
class App extends React.Component{
render(){
return (
<Welcome name={this.a} age={this.props.age}/>
)
}
props只能读不能修改
state&生命周期
// 在constructor中定义,setState是唯一能改变的state的地方
class Clock extends React.Component{
constructor(props){
super(props);
this.state = {
date: new Date(),
name: ""
}
}
tick(){
// 只修改了date,name被完整地保留
this.setState({
date: new Date()
})
// setState是异步的,直接使用this.state + this.props可能会修改不成功,所以使用回调函数,state是上一次的state
// this.setSate((state, props) => ({
// name: state.name + props.name,
// }))
}
render(){
return (
<div>
<h1>Hello,World!</h1>
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
)
}
}
生命周期主要分为3个阶段:mount、update、unmount
mount(装载):
constructor:初始化state,绑定this环境,props本地化
componentWillMount:每一个组件render之前,还不能修改state
render:必须有返回值,返回null或者false表示不渲染任何DOM元素
componentDidMount:挂载完成,在所有子组件render之后调用
update(更新):
componentWillReceiveProps(nextProps): 组件更新和父组件render调用时执行,nextProps是要更新的props
shouldComponentUpdate(nextProps, nextState):返回bool值,true更新,false不更新
componentWillUpdate: 预更新函数。
render
componentDidUpdate:更新完成
unmount(卸载):
componentWillUnmount:删除前
事件处理
阻止默认事件不能返回false,必须显示调用:e.preventDefault();
要绑定this,不然在函数内被click回调时this为undefined
// 绑定this有3种方法
// 1. class fields
handleClick = () => {
...
}
<button onClick={this.handleClick}>click</button>
//
handleClick(){
...
}
// 2. 回调中使用箭头函数,可能会进行额外的渲染,一般不用这种
<button onClick={() => this.handleClick()}>click</button>
// 3. bind绑定
<button onClick={this.handleClick.bind(this)}>click</button>
条件渲染
// 1. 判断
if(...){
return ...
}else{
return ...
}
// 2. &&
{true && 表达式} // 返回的是表达式
{false && 表达式} // 返回的是false
// 3. 三目运算符
{n > 0 ? 表达式 : 表达式}
不满足要求的可以return null,不会影响组件的生命周期
列表&Key
循环能像js代码一样进行循环,map、for等等
循环都要添加key
受控组件 (input、textarea、select)
受控组件要自己进行双向绑定,在标签内绑定value和onChange
当只绑定value不绑定onChange时,组件的内容不能修改
当只绑定value不绑定onChange,但绑定的value为null或者undefined时,组件的内容能够改变
<form>
<input name="input" value={this.state.input} onChange={this.handleChange} /><br/>
<textarea name="area" value={this.state.area} onChange={this.handleChange}></textarea><br/>
<select name="select" value={this.state.select} onChange={this.handleChange}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select><br/>
<button onClick={this.handleClick}>click</button>
</form>
handleChange(e){
this.setState({[e.target.name]: e.target.value})
}
状态提升
------------------------------
组合 vs 继承
react中还没需要使用继承组件的情况,所以没有,都是用组合来进行整合
props.children相当于是vue中的slot(插槽),会填充进去对应的位置,其他变量都是props,可以是任何值,包括jsx
function Persion(props) {
return (
<div>
<h1>Persion</h1>
{props.left}{props.right}
<br/>
{props.children}
</div>
)
}
const dom = <Persion left={<input value="input"/>} right={<textarea value="area"/>}>
<h2>children</h2>
<br/>
<hr/>
</Persion>
class App extends React.Component{
render(){
return (
<Persion left={<input value="input"/>} right={<textarea value="area"/>}>
<h2>children</h2>
<br/>
<hr/>
</Persion>
)
}
}