React 基础、jsx语法、组件的基本使用、事件处理(笔记)

本文详细介绍了React的基础使用,包括CDN引入、jsx语法、组件(函数式和类式组件)的创建及使用,重点讲解了组件的state、props和refs属性,以及React中的事件处理和表单数据收集方法。通过实例展示了如何在React中管理状态、传递属性和获取DOM元素。
摘要由CSDN通过智能技术生成

1. React的基本使用

1.1 CDN引入所需要的文件

CDN引入需要三个文件

<!--
  React:react核心库
  React-dom:用于支持react操作dom
  babel:jsx语法转换,jsx = js + xml
  
  React 相关的需要在官网下载,babel 可以在 BootCDN 中找
-->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>
1.2 在html页面使用jsx语法
<body>
  <!-- 创建容器 -->
  <div id="app"></div>
</body>

<!-- 引入相关文件 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/7.0.0-beta.3/babel.min.js"></script>

<!-- 使用 jsx 语法 -->
<script type="text/babel">
  // 创建虚拟 dom
  const VDOM = <h1 id="title">hello React</h1>
  
  // 渲染虚拟 dom 到页面上
  ReactDOM.render(VDOM, document.getElementById("app"))
</script>

<!-- 使用 js 语法,这种方式不需要 babel 转换,但是比较繁琐,以后可能不经常使用 -->
<script>
  // 创建虚拟 dom
  const VDOM = React.creatElement("h1", {id: "title"}, "hello React")
  
  // 渲染虚拟 dom 到页面上
  ReactDOM.render(VDOM, document.getElementById("app"))
</script>
1.3 jsx语法规则
  1. jsx 是 js 的衍生,支持 js 语法
  2. 定义虚拟 DOM 时,不要写引号
  3. 标签中混入 JS 表达时不要用引号,要用{}
  4. {} 可以写表达式,不能写语句
  5. 样式的类名指定不要用 class,要用 className
  6. 内联样式要用 style={{ key: value }}的形式去写
  7. 只能有一个根标签
  8. 标签必须闭合
  9. 标签首字母
    • 若小写字母开头,则将该标签转为 html 中同名元素,若 html 中无该标签对应的同名元素,则报错
    • 若大写字母开头,react 就去渲染对应的组件,若组件没有定义,则报错

2. React组件的使用

2.1 函数式组件
  1. 函数必须要有返回值
  2. 函数名对应的组件名,首字母应该大写
  3. 在使用时要使用组件标签
function MyComponent() {
  console.log(this) // window
  return <div>我是一个函数式组件</div>
}

ReactDOM.render(<MyComponent />, document.getElementById("app"))
// 在 render 时先查看标签开头是否为大小写,如果为大写,那么就直接调用该函数
2.2 类式组件
  1. 需要继承 React 内置的组件
  2. 需要有 render 函数,并要有返回值
class MyComponent extends React.component {
  render() {
    console.log(this) // MyComponent {...}
	return <div>我是一个类式组件</div>
  }
}

ReactDOM.render(<MyComponent />, document.getElementById("app"))
// React在解析组件标签时,自动的帮忙 new 了这个类,然后实例自己调用了 render 函数,使用的也是 MyComponent 的实例(组件实例对象)
2.3 组件实例的三大属性
2.3.1 state
  1. state 是做 React 组件实例对象的状态管理,和 Vue 中的 data 一样
  2. 在修改 state 值的时候,需要使用 setState 去修改
  3. 下面的三种方式,都是把属性和方法挂载到组件实例对象上,在类中可以通过 this 去获取
  4. 函数是自己调用的,会改变 this 指向,所以需要写成箭头函数
  5. 每次修改 state 中的值的时候,render 函数都会调用一次
class MyComponent extends React.Component {
  state = {
    msg: "我是一条消息",
  };
    
  render() {
    return <div onClick={this.fn}>{this.state.msg}</div>;
  };
    
  fn = () => {
    let { msg } = this.state;
    this.setState({
      msg: msg + "!",
    });
  };
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));
2.3.2 props
// 在使用之前需要引入 prop-types 文件,也是在 BootCDN 中可以下载
class MyComponent extends React.Component {
  constructor(props) {
    // 在构造函数中,如果需要通过 this 拿到 props 中的值,需要 super(porps),在其他任何地方都可以拿到
    // 在 React 内部把 props 中的值添加到当前实例上了
    super();
    console.log("constructor", this.props); // constructor undefined
  }

  // 数据
  state = {
    msg: "我是一条消息",
  };

  // prop
  static propTypes = {
    name: PropTypes.string.isRequired, // 类型为 String,为必传
    age: PropTypes.number, // 类型为 Number
  };
  // 默认值的配置
  static defaultProps = {
    age: 18,
    gender: "男",
  };

  render = () => {
    console.log("render", this.props); // render {name: '小红', age: 18, gender: '男'}
    let { name, age, gender } = this.props;
    return (
      <div>
        <ul>
          <li>姓名:{name}</li>
          <li>年龄:{age}</li>
          <li>性别:{gender}</li>
        </ul>
      </div>
    );
  };
}

let p = {
  name: "小红",
  age: 18,
  gender: "男",
};

// 传递的数据
// 因为 babel 做了处理,所以组件上可以 ...p 这样写
ReactDOM.render(<MyComponent {...p} />, document.getElementById("app"));

PropTypes中的类型,这点需要注意

  • number
  • string
  • bool
  • symbol
  • bigint
  • object
  • array
  • func
  • any
// 函数式组件使用 props,函数式组件在 React@16.8 只能使用 props
function MyComponent(props) {
  let { name, age, gender } = props;
  return (
    <div>
      <ul>
        <li>姓名:{name}</li>
        <li>年龄:{age}</li>
        <li>性别:{gender}</li>
      </ul>
    </div>
  );
}

let p = {
  name: "小红",
  age: 18,
  gender: "男",
};

// 传递的数据
ReactDOM.render(<MyComponent {...p} />, document.getElementById("app"));
2.3.3 refs
  • 字符串形式的 ref

    // 这种方式效率会慢一些
    class Demo extends React.Component {
      getRefs = () => {
        console.log(this.refs); // {input: input, p: p, span: span}
      };
        
      render() {
        return (
          <div>
            <input ref="input" type="text" />
            <p ref="p">我是p标签</p>
            <span ref="span">我是span标签</span>
            <br />
            <br />
    
            <button onClick={this.getRefs}>点击获取标签</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, document.getElementById("app"));
    
  • 回调函数形式的 ref

    // 这种方式当修改数据时,ref 的回调函数会执行两次,curNode 第一次值为 null,第二次值为当前节点
    // 但是这种方式是无关紧要的,并没有什么影响
    class Demo extends React.Component {
      state = {
        flag: true
      };
        
      getRefs = () => {
        console.log(this.p); // <p>...</p>
      };
        
      changeState = () => {
    	let { flag } = this.state
        this.setState({
    	  flag: !flag
        })
      };
        
      render() {
        return (
          <div>
            <p ref={(curNode) => { 
                      this.p = curNode; 
                      console.log(curNode); 
                    }}>我是p标签</p>
    
            <button onClick={this.getRefs}>点击获取标签</button>
                
            <button onClick={this.changeState}>点击修改数据</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, document.getElementById("app"));
    
    // 可以把函数提出来,这样就只会在最开始调用一次了
    ref = (curNode) => {
      this.p = curNode
    }
    <p ref={this.refP}>我是p标签</p>
    
  • createRef

    // 这种是 React 最推荐的
    class Demo extends React.Component {
      refP = React.createRef(); // 此时的 refP 只能为一个标签使用
        
      getRefs = () => {
        console.log(this.refP.current); // <p>...</p>
      };
        
      render() {
        return (
          <div>
            <p ref={this.refP}>我是p标签</p>
    
            <button onClick={this.getRefs}>点击获取标签</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, document.getElementById("app"));
    

3. React中的事件处理

  1. 通过 onXxx 属性指定事件处理函数 ------ 注意大小写
  2. React 使用的是自定义(合成)事件,而不是使用原生的 DOM 事件 ------ 为了更好的兼容性
  3. React 中的事件是通过事件委托方式处理的 ------ 为了高效
  4. 通过 event.target 得到发生事件的 DOM 元素对象,和原生的一样 ------ 不要过度的使用 ref

4. 收集表单数据

// 这种方式和 vue 中的双向绑定很相似
class Demo extends React.Component {
  state = {
    username: "",
    password: "",
  };

  saveUsername = (e) => {
    this.setState({
      username: e.target.value,
    });
  };

  savePassword = (e) => {
    this.setState({
      password: e.target.value,
    });
  };

  render() {
    return (
      <div>
        账号:<input onChange={this.saveUsername} type="text" name="username" placeholder="请输入账号" />
        密码:<input onChange={this.savePassword} type="password" name="password" placeholder="请输入密码" />
      </div>
    );
  }
}

ReactDOM.render(<Demo />, document.getElementById("app"));
// 使用高阶函数简便写法
class Demo extends React.Component {
  state = {
    username: "",
    password: "",
  };

  saveFormData = (dataType) => {
    return (e) => {
      this.setState({
        [dataType]: e.target.value,
      });
    }
  };

  render() {
    return (
      <div>
        账号:<input onChange={this.saveFormData("username")} type="text" name="username" placeholder="请输入账号" />
        密码:<input onChange={this.saveFormData("password")} type="password" name="password" placeholder="请输入密码" />
      </div>
    );
  }
}

ReactDOM.render(<Demo />, document.getElementById("app"));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值