day:1
关于环境搭建
国内使用 npm 速度很慢,你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:
$ npm install -g cnpm --registry=https://registry.npmmirror.com $ npm config set registry https://registry.npmmirror.com
安装命令:
$ cnpm install -g create-react-app $ create-react-app my-app $ cd my-app/ $ npm start
关于react的webpack配置隐藏问题:默认隐藏,如果显化,不能退回。
参考:
React 安装(NPM) | 菜鸟教程 (runoob.com)
day:2
(基本语法的学习笔记)
初步认识react
<body>
<div id="root"></div>
<!-- 添加依赖 -->
<!-- 依赖三个包 -->
<!-- CDN引入 -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- babel -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
const root=ReactDOM.createRoot(document.querySelector('#root'))
root.render(<h2>Hello World</h2>)
</script>
<!-- 注意事项:
1.根节点id和选择器document.querySelector对应
2.标签类型是 type="text/babel"
-->
</body>
小demo:
代码实现:
<script type="text/babel">
const root=ReactDOM.createRoot(document.querySelector('#root'))
// 1将文本定义成变量
let message='hello world'
// 2监听按钮点击事件
function btnClick(){
message='Hello React'
// 重新渲染页面
root.render((
<div>
<h2>{message}</h2>
<button onClick={btnClick}>修改文本</button>
</div>
))
}
root.render((
<div>
<h2>{message}</h2>
<button onClick={btnClick}>修改文本</button>
</div>
))
// code 注意事项:
// 1、这里的{message}一定区别单双引号,不要和vue的{{}}搞混,否则会报错
渲染部分代码有重复,可以优化一下:
const root=ReactDOM.createRoot(document.querySelector('#root'))
// 1将文本定义成变量
let message='hello world'
// 2监听按钮点击事件
function btnClick(){
message='Hello React'
// 替换为渲染函数
rootRender()
}
// 函数有变量提升,可以在定义前调用
rootRender()
function rootRender(){
root.render((
<div>
<h2>{message}</h2>
<button onClick={btnClick}>修改文本</button>
</div>
))
}
组件化开发:
// 组件化开发:
// 封装组件
class App extends React.Component{
// 数据:数据根据是否参与页面展示分为参与数据流、非参与数据流,这里参与数据流一定是写在构造函数的state中
constructor(){
super()
this.state={
message:'Hello Wold'
}
this.btnClick=this.btnClick.bind(this)
}
// 方法:
// react中的方法因为使用继承的原因,this会变成undefined,因此需要单独处理
btnClick(){
// setState内部完成了两件事:1修改state中的message;2自动重新执行render函数
this.setState({
message:"Hello React"
})
}
// 渲染内容的render方法
render(){
return(
<div>
<h2>{this.state.message}</h2>
<button onClick={this.btnClick}>修改文本</button>
</div>
)
}
}
// 获取渲染根节点
const root=ReactDOM.createRoot(document.querySelector('#root'))
// 将组件渲染到界面上
root.render(<App/>)
code注意事项:
1、事件绑定this可以通过在 <button onClick={this.btnClick.bind(this)}>修改文本</button>这里绑定this(this的修改)
同样也可以在构造函数内部加 this.btnClick=this.btnClick.bind(this)实现绑定this。
2、这里的app实际上就是根组件,其他组件和页面逻辑都可以在app组件的基础上进行扩展延伸
案例1:电影列表:
<!-- 根节点 -->
<div id="root"></div>
<!-- 导入 -->
<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/babel.js"></script>
<script type="text/babel">
// 获取渲染的根节点
const root=ReactDOM.createRoot(document.querySelector('#root'))
// 定义组件
class App extends React.Component{
// 组件数据
constructor(){
super()
this.state={
message:'hello App',
movies:["星际穿越","大话西游","道门空间","少年派的奇幻漂流"]
}
}
render(){
//实现方法1:对movies进行for循坏
// --将电影列表数组转化为li标签列表数组
// const liEls=[]
// for(let i=0;i<this.state.movies.length;i++){
// const movie=this.state.movies[i]
// const liEl = <li>{movie}</li>
// liEls.push(liEl)
// }
return (
<div>
<h2>电影列表</h2>
<ul>
{this.state.movies.map(movie => <li>{movie}</li>)}
</ul>
</div>
)
}
}
// 将组件渲染到根节点
root.render(<App/>)
</script>
注意事项:
列表渲染在react中比较灵活,可以通过各种方式来实现,map方法的箭头函数使用方法更简洁。
错点:const root获取渲染根节点的时候使用错误,没有获取成功报不是一个dom元素。注意:const root=ReactDOM.createRoot(document.querySelector('#root')),按照这个代码检查获取节点。
案例2:计数器
代码
<!-- 根节点 -->
<div id="root"></div>
<!-- 导入 -->
<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/babel.js"></script>
<!-- script代码 -->
<script type="text/babel">
// 获取渲染节点
const root=ReactDOM.createRoot(document.querySelector('#root'))
console.log(root)
// const root=ReactDOM.createRoot(document.querySelector('#root'))
// 定义组件
class App extends React.Component{
// 组件数据
constructor(){
super()
this.state={
count:100,
message:'Hello World'
}
this.increament= this.increament.bind(this)
this.decreament= this.decreament.bind(this)
}
// 渲染内容
render(){
return(
<div>
<h2>{this.state.count}</h2>
<button onClick={this.increament}>+1</button>
<button onClick={this.decreament}>-1</button>
</div>
)
}
// 方法
increament(){
this.setState({
count:this.state.count+1
})
}
decreament(){
this.setState({
count:this.state.count-1
})
}
}
// render函数渲染组件
root.render(<App/>)
</script>
须注意:
1.constructor中给方法绑定this需要采用赋值的方式,如
this.increament= this.increament.bind(this)
2.修改数据使用setState是括号加对象的方式,对象内部是键值对。
this.setState({
count:this.state.count+1
})
配置react代码片段
用于html中练习react,快速生成代码片段
代码:
"creat react app": {
"prefix": "reactapp",
"body": [
"<!DOCTYPE html>",
"<html lang=\"en\">",
"<head>",
" <meta charset=\"UTF-8\">",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
" <title>Document</title>",
"</head>",
"<body>",
" <!-- 根节点 -->",
" <div id=\"root\"></div>",
" <!-- 导入 -->",
" <script src=\"./lib/react.js\"></script>",
" <script src=\"./lib/react-dom.js\"></script>",
" <script src=\"./lib/babel.js\"></script>",
" <!-- script代码 -->",
" <script type=\"text/babel\">",
" // 获取渲染节点",
" const root=ReactDOM.createRoot(document.querySelector('#root'))",
" ",
" // 定义组件",
" class App extends React.Component{",
" // 组件数据",
" constructor(){",
" super()",
" this.state={",
" message:'Hello World'",
" }",
" }",
" // 渲染内容",
" render(){",
" return(",
" <div>",
" <h2>{this.state.message}</h2>",
" </div>",
" )",
" }",
" }",
" // render函数渲染组件",
" root.render(<App/>)",
"",
" </script>",
"</body>",
"</html>"
],
"description": "creat react app"
}
配置步骤:需要在文件-首选项-代码片段中复制进去上面这段代码(注意选择html.json文件)。代码片段的生成也可以自己编辑好模板,然后通过snippet generator网站中生成。
jsx
认识jsx:
const {message}=this.state 实际上就是一段jsx代码,是html in js的写法,react实际上就是all in js.
为什么react选择了jsx:与react设计理念有关系,react设计之初认为js和html代码实际上是不能完全分离的。渲染逻辑与ui界面彼此耦合。
jsx基本使用
js的书写规范:
1.jsx结构中只能有一个根元素
2.jsx结构通常会包裹一个(),将整个jsx当作一个整体,实现换行和机构更好看
3.jsx可以是但标签,也可以双标签,但是但标签必须以/>结尾
jsx中注释的写法:
render(){
return(
<div>
{/*jsx的注释写法(项目中crtl+/自动生成注释*/}
<h2>{this.state.message}</h2>
</div>
)
}
jsx嵌入变量作为子元素:
1)当变量是NUmber、String、Array类型时,可以直接显示
2)当变量是null、undefined、boolean、内容为空,如果希望可以显示null/underfined/boolean那么需要转成字符串
转换方式可以有:toString方法,空字符串拼接,String(变量)等方式
3)object对象类型不能作为子元素(not valid as a Reat child),如果需要展示对象中的key可以使用onject.keys(obj)的方式,或者object.属性名的方式
4)可以插入表达式:2+3、fist+''+last
5) 可以直接当作计算属性使用
6)可以插入三元运算符
7)可以调用方法