react学习笔记

@HuYuee 2017-06-09 02:37:32发表于 iuap-design/blog

image

1. Jsx语法

在html中属性的值通过双引号(字符串数据)或者大括号(表达式)

//双引号
const a = <img src="1.jpg" />

//大括号
const x = "1.jpg"
const a = <img src={x} />

//有子元素的情况,都只能包含在同一个元素内,与vue语法保持一致
const a = (
	<div>
		<h1>标题</h1>
		<span>gogogo</span>
	</div>
)

注意:react对于jsx中的变量都会进行转义,以免xss攻击

2. 渲染DOM

通过reactDOM.render方法来渲染dom节点,并且react元素一旦创建就是不可变的,唯一的办法就是重新创建个新的元素然后重新通过ReacDOM.render去渲染,就是这么cool!😝😝😝。但是每次更新,不是统一将整个元素都更新,都只会修改更新了的元素

function tick(){
  const ele = (
  	<div>
  		<h1>现在的时间是:{new Date().toLocaleTimeString()}</h1>
  	</div>
  );
  ReactDOM.render(
  	ele,
  	document.getElementById('root')
  )
}
setInterval(tick,1000);

3. 函数组件开发

当用户看到用户自定义的组件的时候,就会将jsx的属性作为单个对象(props)传递给此组件

function Aiv(props){
  return <h1>hi,{props.name}</h1>
}
const e = <Aiv name = "haha" />;
ReactDOM.render(
	e,
	document.getElementById('root')
)

注意:自定义的组件的首字母必须为大写,否则不能识别

4. Props是只读的

react虽然是非常灵活的,但是有一条严格的规范:props是只读的,虽然也可以改变,但是不推荐。😝😝😝

比如:

//合格的形式
function Aiv (x, y){
	return x+y;
}
//不合格的形式,传参x被修改了
function Aiv (x, y){
  x = x + y;
}

5. 类组件开发

注意事项:

  1. 创建一个es6语法的class类,并且继承自React.Component
  2. 里面有一个render()方法,将原先函数组件的中的内容,如第3点函数组件例子的内容放到此方法中
  3. props用this.props替换
class Aiv extends React.Component{
  render(){
    return <h1>hi,{this.props.name}</h1>
  }
}

PS:相比于函数组件,类组件还多了本地状态和生命周期挂钩。👍👍👍

6. 增加本地状态state

  1. 将render中的this.props替换为this.state

    class Aiv extends React.Component{
      render(){
        return <h1>hi,{this.state.name}</h1>
      }
    }
  2. 在类组件中增加一个constructor方法来初始化this.state

    class Aiv extends React.Component{
      constructor(props){
        super(props);
        this.state = {name:'hy'};
        
      }
      render(){
        return <h1>hi,{this.state.name}</h1>
      }
    }

7. 增加生命周期方法

此系列方法是为了拓展ReacDOM的渲染的不可变性。使用此方法可以动态的去改变dom,让我们拭目以待。

class Aiv extends React.Component{
  constructor(props){
    super(props);
    this.state = {name:'hy'};
    this.i = 1;
  }
  componentDidMount() {
    this.timerID = setInterval(()=>this.setName(),1000);
  }
  componentWillUnmount() {
	clearInterval(this.timerID);
  }
  setName(){
    this.i ++;
    this.setState({name:"hy"+this.i})
  }
  render(){
    return <h1>hi,{this.state.name}</h1>
  }
}
ReactDOM.render(
  <Aiv />,
  document.getElementById('root')
); ;
  1. componentDidMount方法是在ReacDOM渲染dom节点之后执行
  2. componentWillUnmount方法是在该dom节点被删除的时候执行

8. 正确地使用state

1). 不能直接操作state属性

//wrong
this.state.name = "hy1";

//correct
this.setState({
  name: "hy1"
})

2). state更新可能是异步的

React为了性能,支持单次更新中可以批量执行多个setState,所以你不能在setState中使用this.state这种方式来操作state属性。因为this.state可能是之前的属性,还没来得及改变。如下面的例子对比:

//假设count = 1
this.setState({
  count:this.state.count+1
})
this.setState({
  count:this.state.count+1
})
//最后count = 2

但是,setState方法可以除了接收object对象,还可以接收function参数。传入function完美解决异步问题😎😎😎。使用方法:setState( function( prevState,[props] ){} )

this.setState(function(x){
  return {
    count: x.count+1
  }
})
this.setState(function(x){
  return {
    count: x.count+1
  }
})

操练以下

3). state属性可以只更新单个属性

this.state = {
	posts: [],
	comments: []
};

this.setState({
  posts: ['hy']
})

9. state作为参数传递

直接看例子:

<FormattedDate date={this.state.date} />

function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}

等价于下面:

<h2>It is {this.state.date.toLocaleTimeString()}.</h2>