第一次正式接触react
想表达的一些话。2022年5月5日,目前还在浙江师范大学,离毕业还有一个多月,非常珍惜能够在学校的日子,学生的这个身份好舍不得,努力抓住最后的时间去学习,去玩,去感受,在浙江,在金华,在浙师的日子我真快乐。马上要步入工作,做了很多心理建设,才接受了自己要去北京这个事实,在我过去20多年的人生里,好像越求什么越得不到什么!求之不得没有人比我更懂了吧!从高考,在这之前高中特别讨厌计算机也不愿意去师范学校,可是命运却好像老爱捉弄我,让我读了一个师范学校的计算机专业,唉....,不过好在最后喜欢上了计算机且计算机发展不错也算是歪打正着。于是选择考研,特别清晰的目标是工科学校,杭州,当初的想法是我一定要来杭州。可是命运再一次捉弄了我,又来到了某小城市的师范学校,唉...,不过好在研究生期间也做出来成果遇到的老师和师门都还不错。这一次就是工作了,我说我发誓要留在杭州,可是...,结果你也看到了吧,正如开头所说的,还是无奈的签下了北京的公司...,唉....,就这样吧我没有执念了...,试着接受老天安排的一切!
react基础
1、babel.min.js (es6转es5) react是jsx,jsx转js
2、react.development.js react核心库
3、react-dom.development.js扩展库
一、JSX语法规则
<script type="text/babel"> /* 此处一定要写babel */
const myId = 'heima'
const myData = 'hello react'
//1.创建虚拟DOM
const VDOM = (
<div>
<h2 className="title" id={myId}>
<span style={{ color: 'pink', fontSize: '20px' }}>{myData}</span>
</h2>
<input type="text" />
<good>123</good>
</div>
)
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById('test'))
jsx语法规则:
1.定义虚拟DOM时,不要写引号。
2.标签中混入JS表达式时要用{}。
3.样式的类名指定不要用class,要用className
4.内联样式,要用style={{key:value}}的形式去写。
5.只有一个根标签
6.标签必须闭合
7.标签首字母
(1)若小写字母开头,则将标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
(2)若大写字母开头.react就去渲染对应的组件,若组件没有定义,则报错。
</script>
JSX小练习---动态展示前端框架
一定注意区分:【js语句(代码)】与【js表达式】
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些都是表达式:
(1) a
(2) a+b
(3) demo(1)
(4) arr.map()
(5) function test(){}
2.语句:
下面这些是语句
(1) if(){}
(2) for(){}
(3) switch(){case:xxx}
//1.创建虚拟DOM
// 模拟一些数据
const data = ['angular', 'react', 'vue']
const VDOM = (
<div>
<h1>前端js框架列表</h1>
<ul>
{
data.map((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
</div>
)
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById('test'))
二、react中定义组件(函数式和类式)
01.函数式组件
// 1.创建函数式组件 函数首字母必须大写,函数必须有返回值
function MyComponent() {
console.log(this)//此处的this是undefined,因为babel编译后开启了严格模式
return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />, document.getElementById('test'))
执行了ReactDOM.render(<MyComponent /> ...之后,发生了什么?)
1.React解析组件标签,找到了MyComponent组件。
2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟Dom转为真实Dom,随后呈现在页面中。
02.类式组件
// 1.创建类式组件
class MyComponent extends React.Component{
//render是放在哪里的?---MyComponent的原型对象上,供实例使用
// render中的this是谁?---MyComponent的实例对象
render(){
return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<MyComponent />, document.getElementById('test'))
执行了ReactDOM.render(<MyComponent /> ...之后,发生了什么?)
1.React解析组件标签,找到了MyComponent组件。
2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
3.将render返回的虚拟DOM转为真实Dom,随后呈现在页面中
三、组件实例三大属性(state,props,ref)
01.1 state
// 1.创建类式组件
class Weather extends React.Component {
constructor(props) {
super(props)
//借助构造器初试化状态。 state本身为一个空对象,we可以初试化state 状态,然后再读取
this.state = { isHot: true }
}
render() {
return <h1>今天的天气很{this.state.isHot ? "炎热" : '寒冷'}</h1>
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Weather />, document.getElementById('test'))
01.1state的原始模式
// 1.创建类式组件
class Weather extends React.Component {
//构造器执行几次?--1次
constructor(props) {
super(props)
//借助构造器初试化状态。 state本身为一个空对象,we可以初试化state状态,然后再读取
this.state = { isHot: true }
//通过原型链上changeWeather来改变它的this指向,使其指向实例对象,然后再将该方法复制给this.changeWeather属性(方法是特殊的属性)
this.changeWeather = this.changeWeather.bind(this)
}
//render调用几次?---1+n次,1是初始化的那次,n是状态更新的次数
render() {
//react 如何绑定事件 这里把函数名字复制给onClick,等点击时react会帮你调回调
return <h1 onClick={this.changeWeather}>今天的天气很{this.state.isHot ? "炎热" : '寒冷'}</h1>
}
//changeWeather调用几次?---点几次调几次
changeWeather() {
// changeWeather放在哪里?---Weather的原型对象上,供实例使用
// 由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
// 类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
// 获取isHot的值
const isHot = this.state.isHot;
//严重注意:状态不可直接更改,下面这行就是直接更改
// this.state.isHot = !isHot;//错误更改
// 严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换
this.setState({ isHot: !isHot })
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Weather />, document.getElementById('test'))
01.2state简写
<script type="text/babel"> /* 此处一定要写babel */
// 1.创建类式组件
class Weather extends React.Component {
// 初始化状态
state = { isHot: false, wind: '微风' }
render() {
const { isHot, wind } = this.state
return <h1 onClick={this.changeWeather}>今天的天气很{this.state.isHot ? "炎热" : '寒冷'}</h1>
}
// 自定义方法----要用赋值语句的形式+箭头函数
changeWeather = () => {
const isHot = this.state.isHot
this.setState({ isHot: !isHot })
}
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Weather />, document.getElementById('test'))
01.3state总结
1)state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)
2)组件被成为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)
a)组件中render方法中的this为组件实例对象
b)组件自定义的方法中this为undefined,如何解决?
aa:强制绑定this:通过函数对象的bind()
bb:箭头函数
c) 状态数据,不能直接修改或更新
02 props 对props进行限制
<script type="text/babel"> /* 此处一定要写babel */
// 1.创建类式组件
class Person extends React.Component {
// 初始话状态
render() {
const { name, age, sex } = this.props
// this.props.name = 'jack' 此行代码会报错,因为props是只读的
return (
<ul>
<li>姓名:{name}</li>
<li>性别:{sex}</li>
<li>年龄:{age + 1}</li>
</ul>
)
}
}
// 对标签属性进行类型,必要性的限制
Person.protoType = {
name: PropTypes.string.isRequired,//限制name必传,且为字符串
sex: PropTypes.string,//限制sex为字符串
age: PropTypes.number,//限制age为数值
speak: PropTypes.func,//限制speak为函数
}
// 指定默认标签属性值
Person.defaultProps = {
sex: '男',//默认sex为男
age: 18 //默认age为18
}
//2.渲染虚拟DOM到页面
ReactDOM.render(<Person name="jerry" age={19} sex="男" speak={speak} />, document.getElementById('test1'))
ReactDOM.render(<Person name="tom" age={18} sex="女" />, document.getElementById('test2'))
const p = { name: '老刘', age: 18, sex: '女' }
ReactDOM.render(<Person {...p} />, document.getElementById('test3'))
function speak() {
console.log("说话")
}
03 props总结
1、理解
1)每个组件对象都会有props属性
2)组件标签的所有属性都保存在props中
2、作用
1)通过标签属性从组件外向组件内传递变化的数据
2)注意:组件内部不要修改props数据
3、编码操作
1)内部读取某个属性值
this.props.name
2)对props中的属性值进行类型限制和必要性限制
第一种方式(react15.5开始弃用)
Person.propTypes={
name:React.PropTypes.string.isRequried,
age:React.PropTypes.number
}
第二种方式(新)
使用prop-types库进行限制(需要引入prop-types库)
Person.propTypes={
name:PropTypes.string.isRequired,
age:PropTypes.number,
}
3)扩展属性:将对象的所有属性通过props传递
<Person {...person}/>
4) 默认属性值
Person.defaultProps={
age:18,
sex:'男'
}