react入门基础知识总结

React

React是一个用于构建用户界面的JavaScript库,即操作DOM将数据渲染到HTML视图中

为何使用React?

不管使用原生JS还是Jquery操作DOM,浏览器都会进行大量的重排重绘。原生JS没有组件化,代码复用率低。

React特点:

  1. 组件化,声明式编码(相比于命令式编码,一步一步命令去执行,声明式只需使用对应语法,react会来执行对应操作)
  2. React Native可以进行移动端开发。
  3. 虚拟DOM+Diffing算法,减少与真实DOM的交互

依赖包

  • babel,除了将ES6转为ES5,还可以将JSX转为JS
  • react,react的核心宝
  • react-dom,扩展包用于react操控DOM

react必须在react-dom之前引入

虚拟DOM创建的两种方式

JS创建——creatElement

  1. 安装

npm install react react-dom

  1. 引入js文件
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
  1. 创建react元素
// 参数:元素名称,元素属性,元素的子节点(第三个及其以后的参数)
const h1 = React.createElement('h1', { title: 'h1 tag' }, 'h1 tag', React.createElement('h2', null, 'h2 tag'))
  1. 渲染react元素

ReactDOM.render()

<div id="root"></div>
<script>
  // 参数:要渲染的react元素,挂载的位置
	ReactDOM.render(h1, document.getElementById('root'))
</script>

JSX

<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="./dependency/babel.min.js"></script>

<script type="text/babel">
	// 前提已经引入react, react-dom, babel
  // 1.创建虚拟DOM
  const VDOM = (
  	<h1 id="title">
  		<span>Hello,React</span>
  	</h1>
  )
	// 2.将虚拟DOM渲染到真实DOM上
	ReactDOM.render(VDOM, document.getElementById('root'))
</script>

使用JSX可以使得创建虚拟DOM更加简单。经过Babel编译,JSX语法变成JS的语法。
JSX语法规则:

  1. 定义虚拟DOM不要使用引号,为了阅读可以使用括号()
  2. 标签中混入JS表达式使用花括号{}(注意里面是JS表达式,表达式不同于语句,会产生一个值,可以放在任何需要该值的地方,比如console.log该值)
  3. 样式的类名指定不要用class,而用className
  4. 内联样式,要用{{key:value}}形式,最外层花括号表示要用JS表达式,最里层花括号表示一个对象,key为驼峰式
  5. 虚拟DOM必须只有一个跟标签
  6. 标签首字母若小写开头,则转为HTML中同名标签;若大写开头,渲染对应的自定义组件。

组件

函数式组件

// 1.创建函数式组件(自定义组件要大写)
function Demo() {
	return <h2>我是函数式组件</h2>
}
// 2.渲染组件到页面(调用该函数,将返回的虚拟DOM转为真实DOM,渲染到页面中)
ReactDOM.render(<Demo />, document.getElementById('root'))

类式组件

// 1.创建类式组件
class MyComponent extends React.Component {
  // render函数放在MyComponent的原型对象上
	render() {
		return <h2>我是类式组件</h2>
	}
}
// 2.渲染组件到页面(new该类的实例即MyComponent类,并调用该实例原型对象的render方法,获得返回的虚拟DOM,将返回的虚拟DOM转为真实DOM,渲染到页面中)
ReactDOM.render(<MyComponent/>, document.getElementById('root2'))

简单组件&&复杂组件:有状态state的就是复杂组件。

state状态

维护组件内部的状态数据,组件的状态数据改变时,组件会再次调用 render() 方法重新渲染。
添加state创建一个有状态的组件:

class Weather extends React.Component{
  constructor(props){
    super(props)
    this.state = {isHot: false}
  }
  render() {
    return <h2>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
  }
}
ReactDOM.render(<Weather/>, document.getElementById('root'))

【注】:

  1. 更改state状态不能直接修改,通过setState({})来修改

props

传入props小案例:

class People extends React.Component {
  render() {
    const { name, age, sex } = this.props
    return (
      <ul>
        <li>姓名:{name}</li>
        <li>年龄:{age}</li>
        <li>性别:{sex}</li>
      </ul>
    )
  }
}
ReactDOM.render(<People name="randy" age="16" sex="male" />, document.getElementById("root"))

// 函数式组件也可以使用props
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

对props进行类型检查

除了使用Flow,TypeScript进行检查,内置也可以完成,需要使用库import PropTypes from 'prop-types'

People.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.string,
  sex: PropTypes.string
}
People.defaultProps = {
  age: '18',
  sex: '不男不女'
}

详情参考(使用 PropTypes 进行类型检查)

refs

官网参考链接

字符串形式

字符串形式的ref,可以快速获取元素节点,而不用使用document.getElement,小Demo:
(不建议使用)

class Demo extends React.Component {
  showData = () => {
    const input = this.refs.input1
    alert(input.value)
  }

  showText = () => {
    const input = this.refs.input2
    alert(input.value)
  }

  render() {
    return (
      <div>
        <input ref="input1" type="text" placeholder="点击按钮提示数据" />
        <button onClick={this.showData}>点击提示左边数据</button>
        <input ref="input2" onBlur={this.showText} type="text" placeholder="失去焦点提示数据" />
      </div>
    )
  }
}

回调形式

回调形式的ref,上面的改写:

class Demo extends React.Component {
  showData = () => {
    alert(this.input1.value)
  }

  showText = () => {
    alert(this.input2.value)
  }

  render() {
    return (
      <div>
        {// 也可以将回调形式写成类绑定的函数,原因详见官网}
        <input ref={currentNode => this.input1 = currentNode} type="text" placeholder="点击按钮提示数据" />
        <button onClick={this.showData}>点击提示左边数据</button>
        <input ref={currentNode => this.input2 = currentNode} onBlur={this.showText} type="text" placeholder="失去焦点提示数据" />
      </div>
    )
  }
}

createRef()

最新的写法,上面的改写:

class Demo extends React.Component {
  myRef = React.createRef()
  myRef2 = React.createRef()
  showData = () => {
    alert(this.myRef.current.value)
  }

  showText = () => {
    alert(this.myRef2.current.value)
  }

  render() {
    return (
      <div>
        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />
        <button onClick={this.showData}>点击提示左边数据</button>
        <input ref={this.myRef2} onBlur={this.showText} type="text" placeholder="失去焦点提示数据" />
      </div>
    )
  }
}

表单

有关受控组件与非受控组件,官网很详细,参考官网受控组件非受控组件

事件处理

<!-- 传统HTML事件处理-->
<button onclick="activateLasers()">
  Activate Lasers
</button>

<!-- React中事件处理-->
<button onClick={activateLasers}>
  Activate Lasers
</button>

注意:

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
  • onClick={activateLasers}这里函数后面不要加括号,如果这样,相当于把函数的返回值赋给了onClick。
  • React中的事件采用的是事件委托(将事件委托给最外层元素),高效
  • 可以通过event.target获取当前DOM元素,不要过度使用ref

Demo1:点击文字,更改类式组件的state值:

class Weather extends React.Component{
  constructor(props){
    super(props)
    this.state = {isHot: false}
    // 解决changeWeather中this为undefined的情况,重新bind this生成的新函数赋值到实例对象上
    this.changeWeather = this.changeWeather.bind(this)
  }
  render() {
    return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
  }
  changeWeather() {
    // changeWeather放在Weather的原型对象上,供实例使用
    // 没有调用changeWeather,仅仅是把changeWeather方法作为onClick的回调,所以不是通过实例调用的,而是直接调用
    // class中方法默认开启了严格模式,所以此处的this为undefined
    console.log(this)
    
    const isHot = this.state.isHot
    this.setState({isHot: !isHot})
  }
}
ReactDOM.render(<Weather/>, document.getElementById('root'))

上面内容的简写方式:

class Weather2 extends React.Component {
  state = { isHot: false }

  render() {
    return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
  }

  changeWeather = () => {
    const isHot = this.state.isHot
    this.setState({ isHot: !isHot })
  }
}
ReactDOM.render(<Weather2 />, document.getElementById('root2'))

向事件处理函数传递参数:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

生命周期

生命周期图谱
详情参考生命周期API

// 组件render之后,被挂载到页面上调用
componentDidMount() {
}

// 组件将被卸载后调用
componentWillUnmount() {
}

Diff算法

根据新数据生成新的虚拟DOM,为什么key不要用index?新的DOM与旧的DOM进行比较时,依赖的是key,这样可能会造成效率问题,比如在数组开头插入,甚至有可能产生错误。

脚手架

npx create-react-app my-app
cd my-app
npm start

npx命令使得无需安装脚手架包即可进行使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值