【React基础入门】

基于React18.1.0版本

概念

React是一款用于构建用户界面的 JavaScript 库,它的特点:

  1. 声明式UI
  2. 组件化
  3. 跨平台编写

搭建初始化开发环境

  1. 使用脚手架创建

    执行命令 npx create-react-app react-basic(项目名) 进行创建

  2. 启动npm start 或 yarn start

src中核心文件

​ App.js 根组件

​ index.js 应用入口文件

​ index.css 全局样式文件

注意把index.js中的严格模式去掉(react.strictMode),会影响useEffect的执行时机

JSX基础

作用在React中创建HTML结构

​ 柔和了HTml和JS

JSX表达式

​ 可用的表达式

	1. 字符串、数值、布尔值、null、undefined、object ([]、{})
	2. 1+2、‘awd’.split(‘,’),['a','b'] .join('-')
	3. fn()

特别注意

​ if语句/switch-case/变量声明语句/不是表达式,不能在{}中

  1. JSX列表渲染通过map
条件渲染
1.	三元表达式
2.	&&

​ flase&&‘不会显示’

​ true&&‘显示’ —前边的条件为true后边才会展示

原则:模板中的逻辑尽量保持精简

复杂的多分支逻辑 收敛为一个函数,模板只负责调用

JSX样式处理
  1. 行内样式 – 在元素上绑定一个style属性即可 style={{color:red}} //注意驼峰,过长可以收敛为对象

  2. 类名样式

    ​ 在元素上绑定ClassName 引入css文件

注意事项

1.	JSX中必须有一个根节点,若没有可以使用<></>幽灵节点替代
2.	所有标签必须形成闭合
3.	属性名采用驼峰命名法
4.	支持多行/换行,如果换行需要使用 ()包裹防止BUG

格式化配置

	1. 安装VS code prettie
	2. 错误提示工具  Error Lens

安装VS code prettie工具后,修改json文件如下—这是结合vue,react,微信小程序

{
  "git.enableSmartCommit": true,
  // 修改注释颜色
  "editor.tokenColorCustomizations": {
    "comments": {
      "fontStyle": "bold",
      "foreground": "#82e0aa"
    }
  },
  // 配置文件类型识别
  "files.associations": {
    "*.js": "javascript",
    "*.json": "jsonc",
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript"
  },
  "extensions.ignoreRecommendations": false,
  "files.exclude": {
    "**/.DS_Store": true,
    "**/.git": true,
    "**/.hg": true,
    "**/.svn": true,
    "**/CVS": true,
    "**/node_modules": false,
    "**/tmp": true
  },
  // "javascript.implicitProjectConfig.experimentalDecorators": true,
  "explorer.confirmDragAndDrop": false,
  "typescript.updateImportsOnFileMove.enabled": "prompt",
  "git.confirmSync": false,
  "editor.tabSize": 2,
  "editor.fontWeight": "500",
  "[json]": {},
  "editor.tabCompletion": "on",
  "vsicons.projectDetection.autoReload": true,
  "editor.fontFamily": "Monaco, 'Courier New', monospace, Meslo LG M for Powerline",
  "[html]": {
    "editor.defaultFormatter": "vscode.html-language-features"
  },
  "editor.fontSize": 16,
  "debug.console.fontSize": 14,
  "vsicons.dontShowNewVersionMessage": true,
  "editor.minimap.enabled": true,
  "emmet.extensionsPath": [
    ""
  ],
  // vue eslint start 保存时自动格式化代码
  "editor.formatOnSave": true,
  // eslint配置项,保存时自动修复错误
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  },
  "vetur.ignoreProjectWarning": true,
  // 让vetur使用vs自带的js格式化工具
  // uni-app和vue 项目使用
  "vetur.format.defaultFormatter.js": "vscode-typescript",
  "javascript.format.semicolons": "remove",
  // // 指定 *.vue 文件的格式化工具为vetur
  "[vue]": {
    "editor.defaultFormatter": "octref.vetur"
  },
  // // 指定 *.js 文件的格式化工具为vscode自带
  "[javascript]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  // // 默认使用prettier格式化支持的文件
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "prettier.jsxBracketSameLine": true,
  // 函数前面加个空格
  "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
  "prettier.singleQuote": true,
  "prettier.semi": false,
  // eslint end
  // react
  // 当按tab键的时候,会自动提示
  "emmet.triggerExpansionOnTab": true,
  "emmet.showAbbreviationSuggestions": true,
  "emmet.includeLanguages": {
    // jsx的提示
    "javascript": "javascriptreact",
    "vue-html": "html",
    "vue": "html",
    "wxml": "html"
  },
  // end
  "[jsonc]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  // @路径提示
  "path-intellisense.mappings": {
    "@": "${workspaceRoot}/src"
  },
  "security.workspace.trust.untrustedFiles": "open",
  "git.ignoreMissingGitWarning": true,
  "window.zoomLevel": 1
}

函数组件

1.	 组件首字母大写
2.	 必须有返回值

​ 使用JS的函数(或箭头函数)创建的组件,就叫函数组件

类组件

​ 使用ES6创建

1. 首字母大写
2. 继承React.Component父类,从而使用父类提供的方法或属性
3. 必须提供render方法,render必须有返回值,表示该组件的UL结构
事件绑定
1. on+事件名称={事件处理程序}

Class组件放到render()同级,避免this指向问题

注意点: 类组件绑定需要+this

实现对象e

​ 事件回调函数中传入e,就能拿到事件对象e

​ 可以用来阻止默认行为,比如a标签 e.preventDefault()就不会跳走了

传递自定义参数

​ 改造成箭头函数调用执行方式

组件状态

​ 1. 初始化状态

原生使用

1. 添加一个DOM容器到HTML

2. 添加 Script 标签

官方CDN链接

//这里我是保存到本地引入
<body>
  <div id="box"></div>
</body>
<script src="./lib/react.development.js"></script>
<script src="./lib/react-dom.development.js"></script>
<script src="./lib/babel.min.js"></script>
<script type="text/babel">
  const box = document.querySelector("#box")  //获取盒子
  const root = ReactDOM.createRoot(box) //作为根节点
  //root.render(<div>123</div>)  //1.直接渲染
  const e = React.createElement   //2.创建一个虚拟dom函数进行渲染
  root.render(e('div', {
    className: 'children', onClick: () => {
      console.log(6);//采用驼峰命名,事件,类名,……
    }
  }, 'div的内容',
    e('p', { className: 'br' }, 'div内还能嵌套')))
</script>

此刻内容已渲染完成,注意如果有多个渲染同一个容器,后面的会将前面的覆盖掉

JSX基础语法

const box = document.querySelector("#box")  //获取盒子
const root = ReactDOM.createRoot(box) //作为根节点
  let user = {
    mise: '相遇',
    m: '雨天'
  }
  function Mise(i) {
    return '在' + i.m + i.mise
  }
   // JSX写法:
  // const ele = <h1>hello<small>123</small></h1>   //1.嵌入内容
  // const ele = <div >{user.mise}</div>  //2.可以嵌入表达式like
  // const ele = <div >{Mise(user)}</div>    //3.可以是一个表达式
  // root.render(ele)

  // React.createElement写法:
  const ele = React.createElement(
    'h1',
    { className: 'greeting' },
    'Hello, world!'
  );
  root.render(ele)

组件写法

  const box = document.querySelector("#box")  //获取盒子
  const root = ReactDOM.createRoot(box) //作为根节点

  //1.函数组件
  // function Fn(params) {
  //   return (<div>{params.content}我爱你</div>)
  // }
  // root.render(<Fn content='今天星期八' />)

  //2.class组件
  // class Fn extends React.Component {
  //   render(props) {
  //     return <div>我爱你{this.props.content}</div>
  //   }
  // }
  // root.render(<Fn content='今天星期八' />)

  function Fn(params) {   //形参接收传递过来的值
    return (<div>{params.content}我爱你</div>)  
  }
  root.render(<Fn  content='今天星期八' />) //标签上进行传值
  ↓  ↓  ↓ 页面也会渲染

组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
组件内部也可以再嵌套组件

state

  1. 不要直接修改 State

this.setState({name: ‘Hello’});//正确修改姿势

  1. State 的更新可能是异步的

不要依赖他们的值来更新下一个状态,可能会无法准确更新
要解决这个问题,可以让 setState() 接收一个函数而不是一个对象这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
  1. 单向数据流

生命周期

1. 当组件实例被创建并插入 DOM 中时生命周期顺序如下
  1. constructor 初始化 state 或进行方法绑定时使用
  2. static getDerivedStateFromProps()调用 render 方法之前调用
  3. render()唯一必须实现
  4. componentDidMount()类似于vue中的mounted,在组件挂载后(插入 DOM 树中)立即调用
2.组件的 props 或 state 发生变化时会触发更新时
  1. static getDerivedStateFromProps(props, state) 调用 render 方法之前调用,目的让组件在 props 变化时更新 state
  2. shouldComponentUpdate(nextProps, nextState)在渲染执行之前被调用
  3. render()唯一必须实现
  4. getSnapshotBeforeUpdate()在最近一次渲染输出(提交到 DOM 节点)之前调用
  5. componentDidUpdate更新后会被立即调用
3. 组件从 DOM 中移除时生命周期顺序如下
  1. componentWillUnmount 组件卸载及销毁之前直接调用

事件绑定

命名采用小驼峰式,使用 JSX 语法时你需要传入一个函数作为事件处理函数

  1. 元素上直接使用bind绑定
 <button onClick={this.handleClick.bind(this)}>{this.state.isToggle ? 'ON' : 'OFF'}</button>
 
 组件内接收 ↓↓↓
   handleClick() {
      console.log('handleClick!', this)
      this.setState(preState => ({
        isToggle: !preState.isToggle
      }))
    }
  1. 元素上直接绑定+构造器声明
 1.绑定方法
 <button onClick={this.handleClick}>{this.state.isToggle ? 'ON' : 'OFF'}</button>
 2.在constructor构造器中声明 ↓ ↓ ↓
 this.handleClick = this.handleClick.bind(this)
 3.定义handleClick方法
  handleClick() {
      console.log('handleClick!', this)
      this.setState(preState => ({
        isToggle: !preState.isToggle
      }))
    }
  1. 元素上使用箭头函数绑定
1.使用箭头函数直接绑定
 <button onClick={() => this.handleClick()}>{this.state.isToggle ? 'ON' : 'OFF'}</button>
 2.定义事件绑定的回调函数
   handleClick() {
      console.log('handleClick!', this)
      this.setState(preState => ({
        isToggle: !preState.isToggle
      }))
    }
    //不建议使用此种方法,会引起性能问题

1. 每次渲染回调函数所在的组件,此回调函数都会调用多次
2. 在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染

事件传参

  1. 通过bind绑定传参
1.定义事件
 <button onClick={this.handleClick.bind(this, 1001)}>{this.state.isToggle ? 'ON' : 'OFF'}</button>
 2.接收
 handleClick = (id, e) => {
      console.log('id:', id)
      console.log('e:', e)
      this.setState(preState => ({
        isToggle: !preState.isToggle
      }))
    }
  1. 通过箭头函数绑定传参
1.定义事件
 <button onClick={(e) => this.handleClick(e, 1001)}>{this.state.isToggle ? 'ON' : 'OFF'}</button>
 2.处理函数
  handleClick = (id, e) => {
      console.log('id:', id)
      console.log('e:', e)
      this.setState(preState => ({
        isToggle: !preState.isToggle
      }))
    }

列表渲染&key

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>    <li key={number.toString()}>{number}</li>  ); 
    return (
    	<ul>{listItems}</ul>
    );
}
//key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
const numbers = [1, 2, 3, 4, 5];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<NumberList numbers={numbers} />);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值