React 基础 1

知识点扩展

1 模块导入简写, 3种方式可实现一样的效果
  1 import React, {
    
    Component} from 'react'
  2 import React from 'react' / import {
    
    Component} from 'react'
  3 import React from 'react' / const Component = React.Component

2 状态提升干的事
  1 当兄弟组件之间需要对某些数据进行共享时
  2 把需要被共享的数据, 定义在共同的父组件中, 通过组件通信使用

3 React规范: 一切外部数据都要通过 props传递进来

JSX

1 理解
  1 Jsx 是 JS的一种语法扩展 (语法糖)
  2 非必须, React推荐的语法格式
  3 书写的代码, 优雅, 便于维护
  4 Jsx 可防注入攻击 (XSS)
  5 Jsx 中可以直接写 HTML元素
  6 Jsx 中属性 (className 代替 class) (htmlFor 代替 for) (tabIndex 代替 tabindex)
  
2 使用
  1 核心: React 中的变量都要在 {}中书写
  2 注释: {/* 注释内容 */}

定义组件的俩种方式

1 class 组件类
----------------------------------------------------------------
import React, from 'react'
class P1 extends React.Component{
    
    
  constructor() {
    
      
    super()
    this.state = {
    
      // 声明式变量都定义在这里 -- 变量发生变化 -- 视图自动更新
      msg: '爱情是相互欣赏'
    }
  }
  render(h) {
    
      // 组件视图模板
    // do something
    return (<div> <h3> {
    
    this.state.msg} </h3> </div>)
  }
}
----------------------------------------------------------------

2 函数式组件 == 无状态组件
----------------------------------------------------------------
1 ES5 的方式
  function P2() {
    
    
    // do something
    return (<div> <h3> 单方面的付出不是爱情 </h3> </div>)
  }

2 ES6 箭头函数的方式
  const P3 = () => {
    
    
    // do something
    return (<div> <h3> 爱情里卑微的人永远得不到爱 </h3> </div>)
}

3 ES6 箭头函数的简写
  const P4 = () => (<div> <h3> 爱情从来不是同情和感动 </h3> </div>)
------------------------------------------------------------------------------

组件传值

1 父子组件传值
----------------------------------------------------------------
1 书写子组件元素的时候, 自定义属性: <A1 msg={
    
    'data'}/>  // 传值
2 在子组件中: props.msg  //接收
3 各种组件中的接收示例
  1 class类组件: constructor(props) {
    
    super(props)} --> <h3>{
    
    this.props.msg}</h3>
  2 ES5函数式组件: function A1(props) {
    
    let {
    
     msg} = props}
  3 ES6函数式组件: const A2 = props => {
    
     props.msg}
  4 ES6函数简写: const A3 = ({
    
    msg}) => ( msg)  // 对象的解构赋值
----------------------------------------------------------------

2 子父组件传值
----------------------------------------------------------------
1 书写子组件元素的时候, 自定义事件: <A1 onTest={
    
    (data)=>{
    
    Fn(data)}}/>
2 在子组件中: props.onTest('data')   // 接收自定义事件, 所传参数就是子传父的数据
3 逻辑理解
  1 父组件中定义了事件方法 Fn, 当自定义事件调用的时候就会触发 Fn
  2 这样把自定义事件传给子组件, 在子组件中调用自定义事件, 本质上就是调用了 Fn
  3 在自定义事件调用的过程中, 可以把数据以参数的形式传给父组件的 Fn, 达到子父传数据的效果
4 代码分析
  1 相当于给自定义属性 onTest, 赋值成为了一个箭头函数
  2 那么 props.onTest == (data)=>{
    
    Fn(data)} --> 然后执行这个函数, 并传参
  3 执行这个自定义函数 onTest()的时候, 又去触发了父组件中的 Fn方法, 数据参数顺利到达 Fn
----------------------------------------------------------------

class 类组件中的 state

class类组件中的数据: this.state = {
    
     num: 250}

1 访问变量: this.state.num / let {
    
    num} = this.state
2 修改数据: this.setState(num: 66)  // 新值和旧值没有联系的时候使用该方式
3 修改数据: this.setState(state =>({
    
    num: num+1}))  //新值通过旧值计算而来, 使用该方式

4 理解
  1 不把外部的 props 和自有的 state 交叉赋值
  2 不可以使用 this.setState()方法的位置
    1 render() + constructor() + componentDidUpdate()  // 这3个生命周期函数中
    2 自己封装的渲染方法中
  3 每次调用 this.setState()方法, 都会触发 diff运算
  4 diff 运算干什么的
    1 计算出 DOM中真正变化的部分, 只针对该部分做原生 DOM操作, 而非重新渲染整个页面
    2 脏节点: 就是 DOM中发生变化的那个节点
    3 所以也可以说, diff 运算只会对脏节点进行操作, 而不会影响其他节点

事件绑定

1 常识问题
  1 所有事件必须以 on开头 (包括自定义事件)
  2 事件处理函数的定义位置, 和 render / return 同级, 在组件内部
  3 若事件处理函数接收多个参数, 则最后一个参数默认为事件对象

2 绑定事件的方式
  1 <button onClick={
    
    (e)=>{
    
    console.log('事件对象', e)}}>按钮</button>
  2 <button onClick={
    
    ()=>ck1()}></button>  // 绑定一个定义好的函数方法

3 class 类组件的绑定事件方式
  1 <div onClick={
    
    this.ck1(7)}></div>  // 通过 this调用组件内的方法
  2 <div onClick={
    
    ()=>this.ck1(7)}></div>  // 推介使用, 不存在this指向问题
  3 <div onClick={
    
    this.ck1.bind(this, 7)}></div> //方式1给子组件传值, 需指定this指向

4 

渲染相关

1 条件渲染
--------------------------------------------------------------------------
获取变量: bol  (布尔值)
1 {
    
     bol && <h3>哈士奇</h3>}  // bol==true渲染该元素, 反之不渲染
2 {
    
     bol ? <h3>大乌龟</h3> : <h3>小猫猫</h3>}
3 {
    
     idx===1 && <h3>呵呵</h3> } / {
    
     idx===2 && <h3>哈哈</h3>}.. // 多个元素渲染1个
4 上述3的情况, 通常使用 switch语句来封装函数, 也叫自定义的视图渲染方法(效率好一点)
--------------------------------------------------------------------------

2 动态渲染
--------------------------------------------------------------------------
1 <h2 className={
    
    hh}>默晞</h2>   // 通过动态修改 hh的值, 达到更换 class值的效果
2 <h2 style={
    
    {
    
    color:'red', fontSize: 35px}}>默晞<h2/>  // Jsx 中可以这么写样式
3 实现显示隐藏功能 ( 或者通过更改类名都是可以的)
  1 定义变量: display
  2 <h3 style={
    
    {
    
    display}}>呵呵</h3>
--------------------------------------------------------------------------

3 列表渲染
--------------------------------------------------------------------------
1 组件内的声明式变量
  list: [ {
    
    id:1, name: '不甘'},
		  {
    
    id:2, name: '疯子'} ] 

2 渲染数组最常用的方式 (数据处理函数)
  fn() {
    
     return list.map(ele=>(<div key={
    
    ele.id}>{
    
    ele.name}</div>))}
  render() {
    
     return(<div> {
    
    fn()} </div>)}
--------------------------------------------------------------------------

表单

1 非受控表单 -- 用于文件上传 ( 因为所需内存大, 赋值到变量上是不科学的)
---------------------------------------------------------------------
<div>  // 组件视图
  <input id='ipt' type="text"/>  // 1
  <input ref='pass' type="password"/>  // 2
  <input type="file"/>  // 直接上传
  <button onClick={
    
    ()=>this.submit()}></button>
</div>

submit() {
    
      // 组件方法, 获取数据
  const data = {
    
     name: document.getElementById('ipt').value  // 1
				 password: this.refs.pass.value }  // 2
}
---------------------------------------------------------------------

2 受控表单 -- React推介使用 -- (通过声明式变量绑定表单值, 且实现数据双向绑定)
---------------------------------------------------------------------
1 基础使用
this.state = {
    
     name: ''}  // 数据
nameChange(e) {
    
     this.setState({
    
    name: e.target.value})}  // 修改数据
<input value={
    
    this.state.name} onChange={
    
     (e)=>this.nameChange(e)} type="text"/> 

2 方法复用操作 -- 这样其他表单也可以通过这个方法实现数据双向绑定了
formChange(e, key) {
    
     this.state({
    
    [key]: e.target.value}) }

<input 
  value={
    
    this.state.name} 
  onChange={
    
    (e)=>this.formChange(e, 'name')} 
type="text"/>

<input 
  value={
    
    this.state.password} 
  onChange={
    
    (e)=>this.formChange(e, 'password')} 
type="password"/>
---------------------------------------------------------------------

样式定义

1 直接定义样式
---------------------------------------------------------------------
src/pages/A1.js

  1 <he style={
    
    {
    
    fontSize: '20px', color: 'red'}}></h3>

  2 const hh = {
    
    fontSize: '20px', color: 'red'}
  <he style={
    
    hh}></h3>
---------------------------------------------------------------------

2 创建单独的样式文件
---------------------------------------------------------------------
1 src/assets/A1.css  //创建
  1 div {
    
    color: red}

2 src/pages/A1.js //使用
  1 import '../assets/A1.css'
---------------------------------------------------------------------

3 使用插件: styled-components
---------------------------------------------------------------------
1 作用: 可以让我们在 JS文件中,css样式 (可以很好的解决样式冲突的问题)

2 安装: npm i styled-components -S 

3 文件设置: src/pages/styledCss.js  // 可以通过插件让样式写的时候, 有提示
  1 import styled from 'styled-components'
  2 const Div1 = styled.div`font-size: 100px; color: red` // 以字符串的方式定义样式
  3 export {
    
     Div1}

4 使用样式
  1 import {
    
     Div1} from './styledCss'
  2 <Div1> <h3>呵呵</h3> </Div1>  //被该标签包裹的组件视图, 将使用这个导入的样式
---------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/weixin_46178697/article/details/112998011