1、一个最简单的react组件的结构
第一步:导入包
import React from 'react' //react -->创建组件、虚拟dom元素、生命周期
import ReactDOM from 'react-dom' //react-dom --> 把创建好的组件和虚拟dom放到页面上展示
第二步:创建虚拟DOM元素
参数一:创建元素的类型,字符串,表示元素的名称
参数二:是一个对象或者 null,表示当前dom的属性
参数三:子节点(包括 其他 虚拟DOM 获取 文本子节点)
参数N : 其他子节点
const myh1 = React.createElement('h1',{id:'myh1',title:'this is my h1'},'jiangtong')
const mydiv = React.createElement('div',null,'这是一个div元素',myh1)
渲染页面上dom元素的最好方式就是写html代码即 jsx 语法:
const mytest = <div>我的div</div> //会被Babel转义为 React.createElement()调用
第三步:使用ReactDom 把虚拟dom渲染到页面上
参数一: 要渲染的那个dom元素
参数二: 指定放到页面的哪个容器上,需要是一个dom元素,而不是选择器
ReactDOM.render(mydiv,document.getElementById('app'))
2、jsx语法
JSX,是一个 JavaScript 的语法扩展。我们建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。
JSX 中可以嵌入表达式:
const name ='jiangtong'
const myh1 = <h1>my name is,{name}</h1>
ReactDOM.render(myh1,document.getElementById('app'))
JSX 也是一个表达式:
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
其它 :
在jsx控制区域内,需要写js代码,则把他放入{}
在jsx里面写注释 { /* ... */ }
为jsx中的元素添加class类名: 需要用className 来代替 class
在jsx 创建dom的时候,所有的节点,必须由唯一的根元素进行包裹
3、react 创建组件的两种方式
方法一:使用构造函数的方式创建组件
function Hello(props) {
// return null 表明此组件什么都不渲染
return <h1>这是h1 renturn 的组件---{props.name}-{props.age}-{props.gender}</h1>
}
const dog ={
name:'大黄',
age:'3',
gender:'男'
}
ReactDOM.render(<div>
这是我的 div 盒子
<Hello {...dog}></Hello>
</div>,document.getElementById('app'))
小总结:
- 因为是构造函数,首字母要大写
- 在组件中必须返回一个jsx虚拟dom 元素
- props里面的属性是只读的 !!,不可以被重新赋值
- 组件抽离要使用 export default xxx 将其暴露
方法二:使用 class 创建组件
class Movie extends React.Component {
constructor(){
super()
this.state = { // this.state 的数据是可读可写的
msg:'大家好啊,我是可读可写的 !'
} // 相当于 Vue里面的 data(){return{}}
}
render(){ //// render ----渲染当前组件对应的 虚拟dom元素
// this.props.name = 'lisi' 不可,是ready only属性
this.state.msg = 'msg的值被我修改了啊'
return <div>
<h1>这是Movie组件-{this.props.name}-{this.props.age}</h1>
<h3>{this.state.msg}</h3>
</div>
}
}
const user ={
name:'jt',
age:22,
gender:'女'
}
ReactDOM.render(<div>
123
<Movie {...user}></Movie>
</div>,document.getElementById('app'))
小总结:
- super() 其实是父类中 constructor 构造器的一个引用(固定写法)
- 子类中独有的 this 只能写到super下面
两种方式的区别:
1、使用class 关键字创建的组件,有自己的私有数据和生命周期。使用 构造函数创建的组件,只有props,没有自己的私有数据和生命周期
2、用class 创建的组件叫有状态组件,用构造函数创建的组件-----叫无状态组件有无状态组件的本质区别: 有无state 属性和有无生命周期函数
4、props 和 state
props:
function Hello(props){
// Wrong------->props.name = 'zhangsan'
return <div>hello world + {props.name}</div>
}
React.render(
<Hello name="jiangt"/>,
document.getElementById('app')
)
- 构造函数创建的组件使用 props 传递参数
this.props:
class Hello extends React.Component{
constructor(props){
super(props)
}
render(){
return <div>hello + {this.props.name} </div>
}
}
- 在class类创建的组件里面,如果我们要传递参数,要使用 this.props ,同时,必须在constructor以及super里面显式地传递入我们的props。
总结:
- props 是只读的 !!!
- 数据是向下流的,父组件通过props把他的data 传给子组件。
- props不需要我们定义,这个是react里面就存在的一个东西,专门用来存放我们的要传递的参数的
- this.props和props其实是一样性质的,只是在不同的地方有不同的用法。
state:
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = {
msg: 'hello world !',
}
}
render() {
return
<h1>{ this.state.msg }</h1>
}
}
- state 是可读可写的 !!!
- state是私有的数据对象,只会存在class类创建的组件里面。
- 不能直接修改 State,要使用 setState({ key : value })。
- State 的更新可能是异步的,当需要依赖当前状态来改变下一个状态时,可以让 setState() 接收一个函数而不是一个对象。
- 调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。