jsx语法规则
- 定义虚拟dom节点不用引号包裹
- 标签中混入js表达式需要用{}
- 类名的指定不用class,用className
- 内联样式需要用{{key:value}},小驼峰fontSize
- 虚拟dom只能有一个根节点
- 标签必须闭合
注意:react.development.js要在 react-dom.development.js前面引入,react.development.js是基础文件
<div id="test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转换为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
const myId = 'demo'
//虚拟dom
const dom = (
<div>
<h1 id={myId} style={{ color: 'red', fontSize: '18px' }}>为愿博肖揽星河
<span className="green">我与秋风皆过客</span>
</h1>
<h2>并肩与雪山之巅</h2>
<input text="input" />
</div>
)
ReactDOM.render(dom, document.getElementById('test'))
</script>
组件
函数式组件
<script type="text/babel">
//创建函数式组件
function Demo() {
return <h1>不禁你</h1>
}
//渲染组件到页面,组件名称首字母要大写
ReactDOM.render(<Demo />, document.getElementById('test'))
</script>
类式组件
<script type="text/babel">
//创建类式组件
class MyComponent extends React.Component { //创建出来的类需要继承React内置的类Component
render() {
return <h1>每天一口zg的茶</h1>
}
}
//渲染组件到页面,组件名称首字母要大写
ReactDOM.render(<MyComponent />, document.getElementById('test'))
</script>
组件实例的三大属性
state 状态
- 在构造器中初始化state
- state状态值不可直接进行更改,需要借助setState方法去更改状态值
<script type="text/babel">
//创建组件
class Demo extends React.Component {
constructor(props) {
super(props)
//初始化状态
this.state = { flag: false }
//改变this的指向,将getWeather中this的指向改为指向当前的this(实例对象)。前面一个this是原型链上的,后面一个是实例对象身上的,bind会生成一个新的方法
this.changeWeather = this.getWeather.bind(this)
}
render() {
//读取状态
return <h1 onClick={this.changeWeather}>我喜欢{this.state.flag ? "下雨天" : "晴天"}</h1>
}
getWeather() {
// this.state.flag = !this.state.flag //error //状态state不可直接更改,
this.setState({ flag: !this.state.flag }) //需要借助setState进行更改,是进行合并的操作,同名的值进行覆盖
}
}
ReactDOM.render(<Demo />, document.getElementById('test'))
</script>
关于state的简写方式
在类中写赋值语句(state = { flag: false })相当于将state挂载在Demo的实例对象上,getWeather也是一样的
class Demo extends React.Compnent {
state = { flag: false }
render() {
//读取状态
return <h1 onClick={this.getWeather}>我喜欢{this.state.flag ? "下雨天" : "晴天"}</h1>
}
getWeather = () => {
this.setState({ flag: !this.state.flag })
}
}
state的总结
- 组件中的render方法中的this为组件的实例对象
- 状态数据不能直接赋值去修改或者更新,需要借助setState
- 组件自定义中的this指向undefined(在类中会自动开启严格模式,严格模式下的方法中的this全部指向undefined)。解决方法
- 强制绑定this,通过bind去改变this的指向
- 通过箭头函数
props
- PropTypes去约束传入的变量的类型是是否必填项。
- PropTypes是从prop-types.js中引入使用的
- defaultProps、可以设置变量的默认值
<script type="text/babel">
class People extends React.Component {
static defaultProps = { //static 挂载在自己身上
age: 29,
}
static propTypes = {
name: PropTypes.string.isRequired, //限制name的类型必须为字符串,并且必填
age: PropTypes.number,//限制number的类型为number
speak: PropTypes.func
}
render() {
const { name, age } = this.props
return (
<ul>
<li>{name}</li>
<li>{age}</li>
</ul>
)
}
}
const p = {
name: "啵啵",
speak: speak
}
//在react的标签中三点运算符可以将对象展开,在其他地方是不能进行展开的
ReactDOM.render(<People {...p} />, document.getElementById('test'))
function speak() {
}
</script>
refs
1.字符串形式的ref(不推荐使用,比较耗费性能,后面可能会被react弃用)
<input ref='input1' placeholder="点击触发" />
获取方式
this.refs.input1
2.回调函数形式的ref
class Demo extends React.Component {
getClick = () => {
console.log(this.input1.value)
}
getBlur = () => {
console.log(this.input2.value)
}
render() {
return (
<div>
<input ref={(currentNode) => { this.input1 = currentNode }} placeholder="点击触发" /> //this指向类的实例对象,在实例上挂载了一个input1的变量,就是当前dom节点
<button onClick={this.getClick}>点击触发左边输入框事件</button>
<input ref={(currentNode) => { this.input2 = currentNode }} placeholder="失去焦点触发" onBlur={this.getBlur} />
</div>
)
}
}
3.createRef
React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
class Demo extends React.Component {
myRef = React.createRef() //单人单用,每一个都需要建一个
myRef1 = React.createRef()
getClick = () => {
console.log(this.myRef.current.value)
}
getBlur = () => {
const { current } = this.myRef1
console.log(current.value)
}
render() {
return (
<div>
<input ref={this.myRef} placeholder="点击触发" />
<button onClick={this.getClick}>点击触发左边输入框事件</button>
<input ref={this.myRef1} placeholder="失去焦点触发" onBlur={this.getBlur} />
</div>
)
}
}
生命周期
- 组件从创建到死亡的一个过程,会经历一些特定的阶段
- React组件中包含一系列的钩子函数(生命周期回调函数),会在特定的时刻调用
- 我们在定义组件时,会在特定的生命周期回调函数中做特定的操作
生命周期流程图(旧)
生命周期的三个阶段(旧)
-
初始化阶段:由ReactDOM.render()触发初次渲染
- constructor() 构造器
- componentWillMount() 组件即将挂载
- render() 组件页面上渲染
- componentDidMount() 组件挂载完成
-
组件更新阶段:由组件内部的this.setState()或者父组件的render()触发
- shouldComponentUpdate() 组件应该发生更新
- componentWillUpdatu=e() 组件即将更新
- render() 更新渲染
- componentDidUpdate() 组件更新完成
-
注销组件:由ReactDOM.unmountComponetAtNode()触发
- componetWillUnmount() 组件即将卸载
生命周期流程图(新)
生命周期新版本与旧版本的区别
- 新版中即将废弃三个钩子函数
componentWillMount()
componentWillUpdate()
componentWillReceiveProps()
这三个钩子如果想要使用需要加上前缀UNSAFF_,不过在以后的版本可能会被完全弃用掉 - 新增了两个钩子函数
getDerivedStateFromProps
getSnopshotBeforeUpdate