React 全家桶-React基础

  • React 全家桶-React基础已关闭评论
  • 119 次浏览
  • A+
所属分类:Web前端
摘要

用于构建用户界面的JavaScript库。facebook开源、组件化、声明式编码、React Native移动端开发、虚拟DOM+Diffing算法


React 全家桶-React基础

用于构建用户界面的JavaScript库

facebook开源组件化声明式编码React Native移动端开发虚拟DOM+Diffing算法

官网:https://react.docschina.org/

第一章:React的基本使用

1.相关js库

  • react.js:React核心库
  • React-dom.js:提供操作DOM的react扩展库
  • Babel.min.js:解析JSX语法代码转为JS代码的库
    • ES6转ES5

2.创建虚拟DOM的两种方式

  • JSX
  • JS

3.JSX

React定义的一种类似于XML的JS扩展语法:JS + XML

它最终产生的结果不是字符串,也不是HTML/XML标签,而是一个JS对象

语法规则:

  • 标签中混入JS表达式要用{}

    • 表达式:一个表达式会返回一个值,而代码块不一定有值返回

  • 样式的类名指定不要用class属性名,用className

  • 内联样式,要用style={{key: value}}的形式去写

  • 只能有一个根标签

  • 标签必须闭合

  • JSX标签转换规则

    • 若小写字母开头,则将该标签转换为html中同名元素,若html中无该标签对应的同名元素,则报错
    • 若大写开头,则渲染对应的组件,若组件未曾定义,则报错

4.模块化与组件化

模块:向外提供特定功能的js程序,一般是一个js文件

组件:实现局部功能效果的代码和资源的集合

第二章:React面向组件编程

1.基本理解和使用

1.1 React开发者工具

React Developer Tools 浏览器插件

1.2 效果

函数式组件

<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <script type="text/babel">         // 1. 创建函数式组件         function Demo () {             console.log(this) // 此处的this是undefined,因为babel编译后开启了严格模式             return <h2>用函数定义的组件</h2>         }          // 2. 渲染组件到页面         ReactDOM.render(<Demo/>, document.getElementById('ctx'))         /*             渲染步骤:             1. React解析组件标签,找到了了Demo组件             2. 发现组件是使用函数定义的。随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面上         */     </script>     </body> 

类式组件

<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <script type="text/babel">         // 1. 创建类式组件         class MyComponent extends React.Component {             render () {                 console.log(this)                 return <h2>用类定义的组件,适用于复杂组件的定义</h2>             }         }         ReactDOM.render(<MyComponent/>, document.getElementById('ctx'))         /*             渲染步骤:             1. React解析组件标签,找到了了 MyComponent 组件             2. 发现组件是使用类定义的。随后new出该类的实例,并通过该实例调用原型上的render方法,将返回的虚拟DOM转为真实DOM,随后呈现在页面上         */     </script>     </body> 

2.组件三大核心属性

2.1 state

<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <script type="text/babel">         class Weather extends React.Component {             state = {                 isHot: false             }             render () {                 const {isHot} = this.state                 return <h2 onClick={this.changeWeather}>天气:{isHot ? '热' : '凉' },风速:{isHot ? '一级' : '二级' }</h2>             }             // 自定义方法,要用赋值语句+箭头函数(箭头函数没有自己的this)             changeWeather = () => {                 this.state.isHot = !this.state.isHot                 this.setState(this.state)             }         }         ReactDOM.render(<Weather/>, document.getElementById('ctx'))     </script>     </body> 

2.2 props

类式组件使用props
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Person extends React.Component {              // 构造器是否接收props,是否传递给super?问题取决于:是否希望在构造器中通过this访问props             constructor(props) {                 super(props)                 console.log('c', this.props)             }              // 对标签属性进行类型、必要性的限制             static propTypes = {                 name: PropTypes.string.isRequired             }                          // 指定默认值             static defaultProps = {                 sex: '未知'             }              render () {                 const {name, age, sex} = this.props                 return (                     <ul>                         <li>姓名:{name}</li>                             <li>性别:{sex}</li>                             <li>年龄:{age}</li>                         </ul>                 )             }         }                           const p = {name: '逾期', age: 18, sex: '女'}         ReactDOM.render(<Person {...p}/>, document.getElementById('ctx'))     </script>     </body> 
函数式组件使用props
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">                  function Person (props) {             const {name, sex, age} = props             return (                     <ul>                         <li>姓名:{name}</li>                             <li>性别:{sex}</li>                             <li>年龄:{age}</li>                         </ul>                 )         }          // 对标签属性进行类型、必要性的限制         Person.propTypes = {             name: PropTypes.string.isRequired         }                  // 指定默认值         Person.defaultProps = {             sex: '未知'         }                  const p = {name: '逾期', age: 18, sex: '女'}         ReactDOM.render(<Person {...p}/>, document.getElementById('ctx'))     </script>     </body> 

2.3 refs与事件处理

组件内的标签可以定义ref属性来标识自己

2.3.1 字符串形式的refs
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             showData = () => {                 const {input1} = this.refs                 alert(input1.value)             }             showData2 = () => {                 const {input2} = this.refs                 alert(input2.value)             }             render() {                 return (                     <div>                         <input ref="input1" type="text" placeholder="点击按钮提示数据"/>                         <button onClick={this.showData}>点我提示左侧数据</button>                         <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>                     </div>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 
2.3.2 回调函数形式的refs
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             showData = () => {                 const {input1} = this                 alert(input1.value)             }             showData2 = () => {                 const {input2} = this                 alert(input2.value)             }             render() {                 return (                     <div>                         <input ref={c => this.input1 = c} type="text" placeholder="点击按钮提示数据"/>                         <button onClick={this.showData}>点我提示左侧数据</button>                         <input onBlur={this.showData2} ref={c => this.input2 = c} type="text" placeholder="失去焦点提示数据"/>                     </div>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 
2.3.3 createRef
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             myRef = React.createRef()             showData = () => {                 console.log(this.myRef)                 alert(this.myRef.current.value)             }             render() {                 return (                     <div>                         <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>                         <button onClick={this.showData}>点我提示左侧数据</button>                     </div>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 
2.3.4 事件处理

React 全家桶-React基础

2.4 收集表单数据

2.4.1 受控组件
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             state = {                 username: '',                 password: ''             }             saveUsername = (e) => {                 this.setState({username: e.target.value})             }             savePassword = (e) => {                 this.setState({password: e.target.value})             }             handleSubmit = (e) => {                 e.preventDefault() // 阻止form表单提交事件                 const {username, password} = this.state                 alert(`username: ${username.value}, password: ${password.value}`)             }             render() {                 return (                     <form onSubmit={this.handleSubmit}>                         用户名:<input onChange={this.saveUsername} type="text" name="username"/>                         密  码:<input onChange={this.savePassword} type="text" placeholder="password"/>                         <button>login</button>                     </form>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 
2.4.2 非受控组件
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             handleSubmit = (e) => {                 e.preventDefault() // 阻止form表单提交事件                 const {username, password} = this                 alert(`username: ${username.value}, password: ${password.value}`)             }             render() {                 return (                     <form onSubmit={this.handleSubmit}>                         用户名:<input ref={c => this.username = c} type="text" name="username"/>                         密  码:<input ref={c => this.password = c} type="text" placeholder="password"/>                         <button>login</button>                     </form>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 
2.4.3 函数的柯里化
<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Demo extends React.Component {             state = {                 username: '',                 password: ''             }         		/**              * 高阶函数:如果一个函数符合下面两个规范中的任一,那该函数就是高阶函数              * 1. 若A函数接收的参数是一个函数,那么A就可以称之为高阶函数              * 2. 若A函数调用的返回值依然是一个函数,那么A就可以称之为高阶函数              * 函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数,最后统一处理的函数编码形式              */             saveFormData = (dataType) => {                 return (e) => {                     return this.setState({[dataType]: e.target.value})                 }             }             handleSubmit = (e) => {                 e.preventDefault() // 阻止form表单提交事件                 const {username, password} = this.state                 alert(`username: ${username.value}, password: ${password.value}`)             }             render() {                 return (                     <form onSubmit={this.handleSubmit}>                         用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>                         密  码:<input onChange={this.saveFormData('password')} type="text" placeholder="password"/>                         <button>login</button>                     </form>                 )             }         }         ReactDOM.render(<Demo/>, document.getElementById('ctx'))     </script>     </body> 

2.5 组件生命周期

2.5.1 旧版生命周期

React 全家桶-React基础

<body>     <div id="ctx"></div>     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Count extends React.Component {              constructor(props) {                 console.log('Count-constructor')                 super(props)                 this.state = {                     count: 0                 }             }             add = () => {                 const {count} = this.state                 this.setState({                     count: count+1                 })             }             death = () => {                 ReactDOM.unmountComponentAtNode(document.getElementById('ctx'))             }             force = () => {                 this.forceUpdate()             }             componentWillMount() {                 console.log('Count-componentWillMount')             }             componentDidMount() {                 console.log('Count-componentDidMount')             }             shouldComponentUpdate() {                 console.log('Count-shouldComponentUpdate')                 return false             }             componentWillUpdate() {                 console.log('Count-componentWillUpdate')             }             componentDidUpdate() {                 console.log('Count-componentDidUpdate')             }             componentWillUnmount() {                 console.log('Count-componentWillUnmount')             }                          render() {                 console.log('Count-render')                 const {count} = this.state                 return (                     <div>                         <h2>当前求和为: {count}</h2>                         <button onClick={this.add}>点我+1</button>                         <button onClick={this.death}>卸载组件</button>                         <button onClick={this.force}>强制更新</button>                     </div>                 )             }         }                  // 父组件A         class A extends React.Component {             state = {                 carName: '奔驰'             }             changeCar = () => {                 this.setState({carName: '奥迪'})             }             render() {                 return (                     <div>                         <div>A component</div>                         <button onClick={this.changeCar}>换车</button>                         <B carName={this.state.carName}/>                     </div>                 )             }         }         // 子组件B         class B extends React.Component {             // 第一次渲染不会调用这个钩子             componentWillReceiveProps(props) {                 console.log('B-componentWillReceiveProps', props)             }             render() {                 return (                     <div>                         <div>B component: carName={this.props.carName}</div>                     </div>                 )             }         }         // ReactDOM.render(<Count/>, document.getElementById('ctx'))         ReactDOM.render(<A/>, document.getElementById('ctx'))     </script>     </body> 
2.5.2 新版生命周期

React 全家桶-React基础

<body>     <div id="ctx"></div>     <script src="../newjs/react.development.js"></script>     <script src="../newjs/react-dom.development.js"></script>     <script src="../js/babel.min.js"></script>     <!-- 引入prop-types,用于对组件标签进行限制 -->     <script src="../js/prop-types.js" type="text/javascript"></script>     <script type="text/babel">         class Count extends React.Component {              constructor(props) {                 console.log('Count-constructor')                 super(props)                 this.state = {                     count: 0                 }             }             add = () => {                 const {count} = this.state                 this.setState({                     count: count+1                 })             }             death = () => {                 ReactDOM.unmountComponentAtNode(document.getElementById('ctx'))             }             force = () => {                 this.forceUpdate()             }             // 在更新之前获取快照,方法返回值将会作为参数传递给componentDidUpdate钩子             getSnapshotBeforeUpdate () {                 console.log('getSnapshotBeforeUpdate')                 return 'liergou'             }             // getDerivedStateFromProps方法的返回值会作为state的值             static getDerivedStateFromProps (props, state) {                 console.log('getDeriverdStateFromProps', props, state)                 return null             }             componentDidMount() {                 console.log('Count-componentDidMount')             }             shouldComponentUpdate() {                 console.log('Count-shouldComponentUpdate')                 return true             }             componentDidUpdate(preProps, preState, snapshotValue) {                 console.log('Count-componentDidUpdate', preProps, preState, snapshotValue)             }             componentWillUnmount() {                 console.log('Count-componentWillUnmount')             }                          render() {                 console.log('Count-render')                 const {count} = this.state                 return (                     <div>                         <h2>当前求和为: {count}</h2>                         <button onClick={this.add}>点我+1</button>                         <button onClick={this.death}>卸载组件</button>                         <button onClick={this.force}>强制更新</button>                     </div>                 )             }         }         ReactDOM.render(<Count age={88}/>, document.getElementById('ctx'))     </script>     </body> 

2.6 虚拟DOM与DOM Diff算法

https://segmentfault.com/a/1190000012921279

第三章:React应用(基于React脚手架)

第四章:React ajax

第五章:React-router

第六章:React UI 组件库

第七章:Redux