1、安装
cnpm install create-react-app -g create-react-app my-app cd my-app/ npm start
在浏览器中打开 http://localhost:3000/ ,就可以看到默认的界面了~
2、JSX
React
使用JSX(js的语法扩展)来描述用户界面,在JSX中可以使用表达式(用{}包裹)。
const ele = <img src={user.acatarUrl} />
JSX特性更接近js而不是html。React Dom 使用小驼峰命名,比如class
变成className
:
const ele = ( <h1 className ="greet"> Hello,React! </h1> )
3、元素渲染
元素是React
应用的最小单位。使用 ReactDOM.render()
可以将JSX定义的元素渲染到根节点,例如:
<div id="root"></div> <script> const ele = <h1>hello world!</h1>; ReactDOM.render(ele,document.getElementById("root")) </script>
渲染结果:
<div id="root"> <h1>hello world!</h1> </div>
4、父->子通信
- 子组件示例
import React,{ Component } from ‘react‘; class Child extends Component { render(){ return <h1> This is Child: {this.props.name} </h1> } } export default Child;
- 父组件示例
import Child from ‘.Child‘; class App extends Component { render() { return ( <div className="App"> <Child name="heimayu" /> </div> ); } } export default App;
父组件通过<Child name="heimayu" />
直接调用子组件,在组件上定义的属性 name="heimayu"
,render函数可以从this.props
上获取到属性上对应的值。
5、状态
状态(state
)是组件私有的状态属性,具有局部函数的特性。定义:在组件的构造函数中定义,构造函数是唯一能够直接赋值的地方。props
和state
的区别:
- state是当前组件私有,可修改;
- props是调用方定义,无法改变
举例:封装一个简易钟表组件Time
,实时显示当前时间
class Time extends Component { constructor(props){ super(props); // 初始化定义 this.state = { date: this.getNowTime(new Date()) } } // 组件渲染dom后 componentDidMount(){ this.timer = setInterval(()=>{ this.setState({ date: this.getNowTime(new Date()) }) },1000) } // 获取2位数的时间 getTwoNumber(time){ return time.toString().padStart(2,‘0‘); } // 获取当前时间 getNowTime(date){ let y = date.getFullYear(); let M = this.getTwoNumber(date.getMonth() + 1); let d = this.getTwoNumber(date.getDate()); let h = this.getTwoNumber(date.getHours()); let m = this.getTwoNumber(date.getMinutes()); let s = this.getTwoNumber(date.getSeconds()); return `${y}年${M}月${d}日 ${h}时${m}分${s}秒` } render(){ return ( <h2>现在时间是:{this.state.date}</h2> ) } } export default Time;
2个知识点:
-
state
:
- 初始化定义
state
:类组件应始终使用props调用基础构造函数。
constructor(props){ super(props); // 初始化定义 this.state = { date: this.getNowTime(new Date()) } }
- 调用
state
:
{this.state.date}
-
更改状态的方法
setState()
如果在更新的时候,需要使用上一个状态值,需要这样:
this.setState((prevState,props)=>{ prevState 表示上一个状态 props 表示当前组件的属性对象 })
- 生命周期函数:
-
componentWillMount
:组件dom渲染之前 -
render
:组件渲染 -
componentDidMount
:组件dom渲染之后 -
componentWillUpdate
:组件更新前 -
componentDidUpdate
:组件更新后 -
componentWillUnmount
:组件卸载前
6、事件处理
注意事项:
1、类似JS的事件绑定,但是需要使用驼峰;例如:点击事件onClick
;
2、事件中的 this
必须为对应的方法绑定后才能获取,例如:this.clickEvt.bind(this)
;
3、通过 bind
的方法获取参数 e
的方法是在你传入参数的后面进行获取;
class Test3 extends Component { constructor(props) { super(props); this.state = { info: "myinfo:" } // 事件处理可以在这里定义,也可以像下面一样直接在事件的表达式里定义~ // this.clickEvt = this.clickEvt.bind(this,"heimayu","18"); } render() { return ( <h3> 事件处理: <button onClick={this.clickEvt.bind(this,"18")}>点击</button> </h3> ) } clickEvt(name,age,e) { console.log(this.state.info); console.log(name); console.log(age); e.preventDefault(); } }
7、条件渲染
和JS语法一样,可以使用if(){}else{}
语句,例如下面的例子中,使用{TestJSX}
表示条件过滤后的组件。
class App extends Component { constructor(props) { super(props); // 定义一个状态 this.state = { showTextNum: 1 } } render() { // 条件渲染 let TextJSX; if (this.state.showTextNum == 1) { TextJSX = <Text1 /> } else { TextJSX = <Text2 /> } return ( <div className="App"> <button onClick={this.changeState.bind(this)}>切换</button> // 这里使用大括号 {TextJSX} </div> ); } changeState() { this.setState((prevState) => { return { showTextNum: prevState.showTextNum == 1 ? 2 : 1 } }) } }
上面的例子还可以使用三元表达式进行简写:
return ( <div className="App"> <button onClick={this.changeState.bind(this)}>切换</button> { this.state.showTextNum == 1 ? <Text1 /> : <Text2 /> } </div> );
8、列表渲染
通过对数据进行处理,返回对应的渲染出来的JSX模板,例如下例中,使用map
方法遍历listItems
数组,生成列表的JSX模块,因为简单,所以可以直接使用{}写对应的表达式。
render() { const listItems = [{ id:1,name: "heimayu" },{ id: 2,name: "黑玛鱼" }] return ( <div className="App"> // 简单的列表渲染 <ul> { listItems.map(item =>{ return ( <li key={item.id}>{item.name}</li> ) }) } </ul> </div> ); }