步入React
|字数总计:2.6k|阅读时长:11分钟|阅读量:|
2.1 搭建React环境
安装nodejs+vscode,用nvm去管理node版本
2.1.1 create-react-app
文档地址:create-react-app
创建一个项目:npx create-react-app my-app
建一个ts项目:npx create-react-app my-app –typescript
终端输入:yarn eject
(慎用,会把潜藏的react-script弹射到应用层,此操作不可逆)
文档目录
my-app/ README.md node_modules/ package.json public/ index.html favicon.ico robots.txt manifest.json src/ App.css App.js App.test.js index.css index.js logo.svg
|
2.1.2 开始前的配置
安装第三方插件
在vscode商店里下载
module.exports = { printWidth: 100, tabWidth: 2, useTabs: false, semi: false, singleQuote: true, quoteProps: 'as-needed', jsxSingleQuote: true, trailingComma: 'none', bracketSpacing: true, jsxBracketSameLine: false, arrowParens: 'always', rangeStart: 0, rangeEnd: Infinity, requirePragma: false, insertPragma: false, proseWrap: 'preserve', htmlWhitespaceSensitivity: 'css', bracketSpacing: true }
|
可以配置针对该项目的配置文件,在根目录创建.vscode/settings.json
settings.json配置信息
{ "eslint.autoFixOnSave": true, "prettier.eslintIntegration": true, "eslint.enable": true, "files.eol": "\n", "editor.tabSize": 2, "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "eslint.validate": ["javascript", "javascriptreact", "html", "typescript", "typescriptreact"], "files.associations": { "*.jsx": "javascriptreact" },
"typescript.tsdk": "node_modules/typescript/lib", "editor.codeActionsOnSave": { "source.fixAll.eslint": true } }
|
2.1.3 线上项目编辑器
codesandbox
2.2 组件和JSX
2.2.1 编写react元素
react 元素就是一个javascript对象
const element=<h1>hello react</h1> console.log(element); // render方法将react元素渲染到页面上 ReactDOM.render(element, document.getElementById('root'));
// 打印结果 { $$typeof: Symbol(react.element) key: null props:{children: "hello react"} ref: null type: "h1" }
|
2.2.2 jsx
jsx是javascript的语法扩展,使用xml标记的方式直接声明界面
jsx是什么
模版引擎语言Angular和vue中template的语法,js模版的作用就是输入模版的字符串+数据,经过渲染得到渲染过的字符串;jsx不是这样的模版引擎,它是带语法糖的ATX,其实是抽象的语法树,语法糖放到了构建阶段,所以运行的时候不需要解析。
声明示方式创建UI,处理UI逻辑
遵循javascript语法,无学习门槛
react通过babel将jsx转换浏览器识别的语言
bable
const ele=<div className="root"> <p>hello</p> </div>
var ele = React.createElement("div", { className: "root" }, React.createElement("p", null, "hello"));
|
react通过层层嵌套的方法,把我们输入的语句转换成浏览器识别的代码,这就是jsx
背后的原理
jsx 规则
- 在jsx中潜入表达式,用
{}
包裹 - 大写开头作为定义组件,小写tag作为原生的dom节点
- jsx标签可以有特定属性和子元素
- jsx只能有一个根元素
jsx 实践
class main extends Components { constructor(props){ super(props) this.state={ name:"zs", age:12 } } addage(){ return this.state.age+12 } render(){ const flag=true const list = [1, 2, 3] return ( <div className="main"> <p>{this.state.name}</p> <p>{this.state.age>18?'成年':'未成年'}</p> <p>{this.addage.call(this)}</p> {/* 三元表达式判断显示元素 */} { flag? <p>元素1</p> : <p>元素1</p> } {/* 只能用map循环 */} {list.map((item) => { return <div key='item'>{item}</div> })} </div> ) } }
|
jsx需要一个根元素包裹,因为jsx是通过babel进行转译,其实就是通过React.createElement()
,它的第一个参数需要一个元素,如果出现2个就无法识别了
Fragments
用Fragments替换根元素,而且此标签不渲染到页面中
class main extends Components { render(){ return ( <React.Fragment> <p>{this.state.name}</p> <p>{this.state.age>18?'成年':'未成年'}</p> <p>{this.addage()}</p> </React.Fragment> ) } }
class main extends Components { render(){ return ( <> <p>{this.state.name}</p> <p>{this.state.age>18?'成年':'未成年'}</p> <p>{this.addage()}</p> </> ) } }
|
为什么使用Fragments
- 可以包含并列的子元素
- 编写表格组件,包裹子元素让html生效
2.2.3 拓展学习资料
Babel和ATS 抽象语法树1
Babel和ATS 抽象语法树2
2.3 props、列表渲染、条件渲染
什么是props?
当react元素作为自定义组件,将jsx所接受的属性转换成单个对象传递给组件,这个对象被称为“props”(就是父组件传递给子组件的对象)
- props是组件的固有属性
- 不可在组件内部对props进行修改
- 更新props:需要通过父组件重新传入新的props,更新子组件(单向数据流)
2.3.1 示例
const listData={name:'react'} funtion App (){ return ( <div> {} <ListItem data={listData}></ListItem> <div> ) }
|
class ListItem extends Component { constructor(props){ super(props) } render() { return ( <div> <div> {} {this.props.data.name} <div> <div> ); } }
|
函数示组件
- 函数组件也叫无状态组件
- 组件内部没有this
- 没有声明周期
改写如下
funtion ListItem (props){ return ( <div> <div> {} {props.data.name} <div> <div> ) }
|
当前组件如果是纯展示组件,可以用函数组件,函数组件是一个纯函数,用函数组件可以得到性能的提升
2.3.2 列表渲染
const listData=[{name:'react',id:1},{name:'vue',id:2}] funtion App (){ return ( <div> {} { listData.map(item=>{ return <ListItem data={item} key={item.id}/> }) } <div> ) }
|
2.3.3 条件渲染
条件渲染的主要方法
- 使用三目运算符
- 使用函数做条件判断
- 使用与运算符 && 判断
class ListItem extends Component { constructor(props){ super(props) } renderList(){ if(this.props.data.name==='react'){ return <div>jsx</div> }else { return <div>template</div> } }s render(){ return ( <div className='listItem'> {/* 使用三目运算符*/} <div className={`thend-grid`${this.props.data.name==='react'?'-blue':'-green'}}> {this.props.data.name==='react'?'jsx':'template'} <div> {/*使用函数做条件判断*/} {this.renderList.call(this)} {/*使用与运算符 && 判断*/} {this.props.data.name==='react' && <div>jsx</div>} <div> ) } }
|
2.3.4 拓展学习资料
列表渲染进阶知识
更多的条件渲染的方式
2.4 CSS in React
2.4.1 行内样式
<div style={{fontSize:18;color:red}}></div>
|
2.4.2 引入css样式表
src/ components/ ListItem/ index.jsx index.css .title{ color:red; }
import './index.css' class ListItem extends Component { constructor(props){ super(props) }
render(){ return ( <div className='listItem'> <span className='title'>header<span> <div> ) } }
|
上面的在index.css写法,里面的样式是全局样式,会造成全局污染,可以用css module解决
css module
- 不使用选择器,使用class名定义样式
- 不层叠class,使用一个class定义样式
- 用过compose来组合
src/ components/ ListItem/ index.jsx index.module.css .title{ color:red; }
import style from 'index.module.css' class ListItem extends Component { constructor(props){ super(props) }
render(){ return ( <div className='listItem'> <span className={style.title}>header<span> <div> ) } }
|
2.4.3 css管理进阶
css管理工具
- Styled-component
- Classnames
src/ components/ ListItem/ index.jsx index.module.css .title{ color:red; } .themd { background:'red' }
import style from 'index.module.css' import classnames from 'classnames/bind' const cls=classnames.bind(style)
import cn from 'classnames' class ListItem extends Component { constructor(props){ super(props) }
render(){ const flag=true const _cn=cn({ 'themd':flag }) return ( <div className='listItem'> {/* css Module+classnames/bind */} {/* css module 结合 classnames 可以添加2个类名 */} <span className={cls('title','themd')}>header<span> {{/* classnames */} <span className={_cn}></span> <div> ) } }
|
2.4.4 扩展
css module
styled component
在React中使用css预编译