React- JSX的基本使用/组件的基本使用

React框架

用于构建用户界面的javascript库
  1. 发送请求获取数据
  2. 处理数据(过滤、整理格式等)
  3. 操作dom呈现页面
react是一个将数据渲染为HTML视图的开源javascript库
 
为什么要学react?
原生js操作dom繁琐,效率低
使用js直接操作dom,浏览器会进行大量的重绘重排
原生js没有组件化编码方案,代码复用低
 
react特点
采用组件化模式、声明式编码,提高开发效率及组件复用率
在react native中可以使用react语法进行移动端开发
使用虚拟dom+优秀的diffing算法,尽量减少与真实DOM的交互
 
学习react需掌握的基础知识
  • 判断this的指向
  • class类
  • ES6语法规范
  • npm包管理器
  • 原型、原型链
  • 数组常用方法
  • 模块化

react基本使用

复制代码
<div id="root"></div>
    <script>
        //创建react元素
        //参数一:元素名称
        //参数二:元素属性
        //参数三及以后的参数:元素的子节点
        const title = React.createElement('h1', null, 'hello react');
        //渲染react元素
        //参数一:要渲染的react元素
        //元素二:挂载点
        ReactDOM.render(title, document.getElementById('root'));
    </script>
复制代码

React脚手架的意义

使用react脚手架初始化项目
初始化项目:npx create-react-app my-app
启动项目,在项目根目录中:npm start
自动跳转浏览器,并且终端中显示succesfully

JSX(React核心内容)

简介

JSX是javascript XML的简写,表示在javascript代码中写XML(html)格式的代码
复制代码
//导入react
import React from 'react'
import ReactDOM from 'react-dom'

// 创建react元素
const title = React.createElement('h1', null, 'hello react !!');

//渲染react元素
ReactDOM.render(title, document.getElementById('root')); 
复制代码

用JSX去做创建元素和渲染元素

复制代码
//导入react
import React from 'react'
import ReactDOM from 'react-dom'

// 使用JSX创建react元素
const title = <h1>hello JSX<span>nnnnnnnn</span></h1>

//使用JSX渲染react元素
ReactDOM.render(title, document.getElementById('root'));
复制代码
注意点:
React元素的属性名使用驼峰命名法
特殊属性名:class->className\for->htmlFor\tabindex->tabIndex
没有子节点的React元素可以用/>结束
推荐:使用小括号包裹JSX,从而避免JS中的自动插入分号陷阱
 

嵌入JS表达式

通过{js表达式} 
注意:js中的对象是一个例外,一般只会出现在style属性中
不能在{}中出现语句(比如:if/for等)
复制代码
//导入react
import React from 'react'
import ReactDOM from 'react-dom'

// 使用JSX创建react元素
const name = 'jack'
const age = 19
const sayJi = () => "hi react"
//JSX自身也是一个js表达式
const dv = <div>我是jsx</div>
const title = (
  <h1>
    hello JSX
    <span>姓名:{name}年龄:{age}</span>
    <p>{3 > 5 ? 1 : 0}</p>
    <p>{sayJi()}</p>
    { dv}
  </h1>)
//使用JSX渲染react元素
ReactDOM.render(title, document.getElementById('root'));
复制代码

JS X的条件渲染

场景loading效果
条件渲染:根据条件渲染特定的JSX结构
复制代码
//条件渲染
const isLoading = true
//if-else
// const loaddata = () => {
//   if (isLoading) {
//     return <div>loading...........</div>
//   }
//   return <div>数据加载完成,此处显示加载后的数据</div>
// }
//三元表达式
// const loaddata = () => {
//   return isLoading ? (<div>loading...........</div>) : (<div>数据加载完成,此处显示加载后的数据</div>);
// }
//逻辑与运算符 只能实现显示或隐藏
const loaddata = () => {
  return isLoading && (<div>loading...........</div>)
}
const title = (
  <h1>
    条件渲染:
    {loaddata()}
  </h1>
)
//渲染
ReactDOM.render(title, document.getElementById('root'));
复制代码

JSX的列表渲染

如果要渲染一组数据,应该使用数组的map方法
注意:渲染列表时应该添加key属性,key属性的值要保证唯一
原则:map()遍历谁,就给谁添加key属性
注意:尽量避免使用索引号作为key
复制代码
//列表渲染
//列表
const songs = [
  { id: 1, name: '冰雨' },
  { id: 2, name: '背叛' },
  { id: 3, name: '晴天' }
];
const list = (
  <ul>
    {songs.map(item => <li key={item.id}> {item.name}</li>)}
  </ul>
)

ReactDOM.render(list, document.getElementById('root'));
复制代码

JSX样式处理

1.行内样式-style
//样式
const list = (
  <div className="title" style={{ color: 'red' }}>
    JSX样式
  </div>
)
ReactDOM.render(list, document.getElementById('root'));

2.类名-className

.title{
text-align: center;
}

 React组件基础

组件介绍

  1. 组件表示页面中的部分功能
  2. 组合多个组件实现完整的页面功能
  3. 特点:可复用、独立、可组合

组件的两种创建方式

1.使用函数创建组件
函数组件:使用JS的函数(或者箭头)创建的组件
约定1:函数名称必须以大写字母开头
约定2:函数组件必须有返回值,且返回值表示改组件的结构
//函数组件
function Hello() {
  return (
    <div>这是第一个函数组件</div>
  )
}
ReactDOM.render(< Hello />, document.getElementById('root'));
const Hello = () => (<div>这是第一个函数组件</div>)

ReactDOM.render(< Hello />, document.getElementById('root'));
2.使用类创建组件
类组件:使用ES6的class创建的组件
约定1:类名称也必须是大写字母开头
约定2:类组件应该继承React.Component父类中提供的方法或属性
约定3:类组件必须提供render()方法
约定4:render()方法必须有返回值,表示改组件的结构
复制代码
//创建类组件
class Hello extends React.Component {
  render() {
    return (
      <div>这是第一个类组件</div>
    )
  }
}
ReactDOM.render(< Hello />, document.getElementById('root'));
复制代码

把组件抽离为独立的JS文件

复制代码
import React from 'react'
//创建组件
class Hello extends React.Component {
    render() {
        return (
            <div>hello ————————</div>
        )
    }
}
//导出组件
export default Hello
复制代码

引入组件

//导入Hello组件
import Hello from './Hello'
ReactDOM.render(< Hello />, document.getElementById('root'));

React事件处理

复制代码
//事件处理
class App extends React.Component {
  //事件处理程序
  handleClick() {
    console.log('单机事件触发!!!');
  }
  render() {
    return (
      <button onClick={this.handleClick}>点击此处</button>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码
复制代码
//通过函数组件绑定事件
function App() {
  //事件处理程序
  function handleClick() {
    console.log('函数组件中事件绑定');
  }
  return (
    <button onClick={handleClick}>点击此处</button>
  )
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

事件对象

复制代码
//事件对象
class App extends React.Component {
  handleClick(e) {
    e.preventDefault()
    console.log('a标签的单机事件触发了');
  }
  render() {
    return (
      <a href="http://itcast.cn" onClick={this.handleClick}>点击,不会跳转</a>

    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

有状态组件和无状态组件

函数组件又称无状态组件,类组件又称有状态组件
状态叫数据
函数组件没有自己的状态,只负责数据显示
类组件有自己的状态,负责更新UI,让页面动起来
 
state的基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
复制代码
//state的基本使用
class App extends React.Component {
  // constructor() {
  //   super()
  //   //初始化state
  //   this.state = {
  //     count: 0
  //   }
  // }
  state = {
    count: 0
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

setState()修改状态

复制代码
//setState的基本使用
class App extends React.Component {

  state = {
    count: 0,
    test: 'a'
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={() => {
          this.setState({
            count: this.state.count + 1
          })
        }}>+1 </button>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码
注意:
  • 状态是可变的
  • 不要直接修改state中的值
  • 数据驱动视图

从JSX抽离事件处理程序

事件绑定this指向
1.箭头函数
复制代码
//事件处理程序
class App extends React.Component {
  state = {
    count: 0,
  }
  onIncrement() {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={() => this.onIncrement()}> +1 </button>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码
2.Function.prototype.bind()
将事件处理程序中的this与组件实例绑定道一起
复制代码
class App extends React.Component {
  constructor() {
    super()
    this.state = {
      count: 0,
    }
    this.onIncrement = this.onIncrement.bind(this)
  }
  onIncrement() {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.onIncrement}> +1 </button>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

第三种方法

复制代码
class App extends React.Component {
  constructor() {
    super()
    this.state = {
      count: 0,
    }
  }
  onIncrement = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.onIncrement}> +1 </button>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

表单处理

1.受控组件

  • HTML中的表单元素是可输入的,也就是有自己的可变状态
  • 而React中可变状态通常保存在state中,并且只能通过setState()方法来修改
  • React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
  • 受控组件:其值收到React控制的表单元素
复制代码
//受控组件,其值受到react控制的表单元素
// 操作文本框的值
class App extends React.Component {
  state = {
    txt: ''
  }
  handleChange = (e) => {
    this.setState({
      txt: e.target.value
    })
  }
  render() {
    return (
      <div>
        <input type="text" value={this.state.txt} onChange={this.handleChange}></input>
      </div>
    )
  }
}


ReactDOM.render(< App />, document.getElementById('root'));
复制代码
复制代码
//受控组件实例
class App extends React.Component {
    state = {
        txt: '',
        content: '',
        city: 'gg',
        isChecked: false
    }
    handleForm = (e) => {
        //获取当前的dom对象
        const target = e.target
        //根据类型获取值
        const value = target.type === 'checkbox' ? target.checked : target.value
        //获取name
        const name = target.name
        this.setState({
            [name]: value
        })
    }
    // handleContent = (e) => {
    //     this.setState({
    //         content: e.target.value
    //     })
    // }
    // handleCity = (e) => {
    //     this.setState({
    //         city: e.target.value
    //     })
    // }
    // handleChecked = (e) => {
    //     this.setState({
    //         isChecked: e.target.value
    //     })
    // }
    render() {
        return (
            <div>
                {/* 文本框 */}
                <input type="text" name="txt" value={this.state.txt} onChange={this.handleForm} />
                <br />
                {/* 复文本框 */}
                <textarea value={this.state.content} name="content" onChange={this.handleForm}></textarea>
                <br />
                {/* 下拉框 */}
                <select value={this.state.city} name="city" onChange={this.handleForm}>
                    <option value="sh">上海</option>
                    <option value="bj">北京</option>
                    <option value="gg">广州</option>
                </select>
                {/* 复选框 */}
                <input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm} />
            </div>
        )
    }
}



ReactDOM.render(< App />, document.getElementById('root'));
复制代码

非受控组件

复制代码
//非受控组件
class App extends React.Component {
  constructor() {
    super()
    //创建ref
    this.txtref = React.createRef()
  }
  //获取文本框的值
  getTxt = () => {
    console.log('文本框的值:', this.txtref.current.value);
  }
  render() {
    return (
      <div>
        <input type="text" ref={this.txtref} />
        <button onClick={this.getTxt}>获取文本框的值</button>
      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

案例:评论列表

复制代码
//案例:评论列表
class App extends React.Component {
  state = {
    comments: [
      { id: 1, name: 'jack', content: '沙发!!!' },
      { id: 2, name: 'tom', content: '沙发!!!' },
      { id: 3, name: 'jonh', content: '沙发!!!' },
    ],
    //评论人 
    userName: '',
    //评论内容
    userContent: ''
  }
  //渲染评论列表
  renderList() {
    return this.state.comments.length === 0 ?
      (<div className="no-comment" >暂无评论,快去评论吧</div>)
      : (<ul>
        {this.state.comments.map(item => (
          <li key={item.id}>
            <h3>评论人:{item.name}</h3>
            <p>评论内容:{item.content}</p>
          </li>
        ))}
      </ul>)
  }
  //处理表单元素值
  handleForm = (e) => {
    const { name, value } = e.target
    this.setState({
      [name]: value
    })
  }
  //发表评论
  addComment = () => {
    if (this.state.userName.trim() === '' || this.state.userContent.trim() === '') {
      alert('请输入评论人和评论内容')
      return
    }
    const newComments = [{
      id: Math.random(),
      name: this.state.userName,
      content: this.state.userContent,
    }, ...this.state.comments]

    this.setState({
      comments: newComments,
      userName: '',
      userContent: ''
    })
  }
  render() {
    return (
      <div className="app">
        <div>
          <input className="user" name="userName" type="text"
            value={this.state.userName} placeholder="请输入评论人"
            onChange={this.handleForm} />
          <br />
          <textarea className="content" name="userContent"
            value={this.state.userContent} cols="30" rows="10" placeholder="请输入评论内容"
            onChange={this.handleForm} />
          <br />
          <button onClick={this.addComment}>发表评论</button>
        </div>
        {/* 通过条件渲染 */}
        {this.renderList()}


      </div>
    )
  }
}
ReactDOM.render(< App />, document.getElementById('root'));
复制代码

 

posted @   终究还是避免不了遗憾  阅读(293)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示