React的基础学习(一)

 官网文档 - https://react.docschina.org/docs/getting-started.html

  本篇文章会介绍react项目利用脚手架如何搭建,以及它的基础语法和属性

1.react项目搭建

    脚手架搭建

  全局安装脚手架  yarn global add create-react-app
  创建项目       create-react-app 项目名
  进入并启动     cd 项目名 =》  yarn start

   注意:

        (1) 有可能会全局安装有问题,则不进行全局安装

 局部安装脚手架 yarn add create-react-app
 创建项目     npx creat-react-app 项目名
 进入并启动项目  cd 项目名 =》 yarn start

       (2)有可能会出现全局安装了webpack 和现在安装的版本不一致,卸掉掉安全局的webpack

npm uninstall webpack -g
yarn remove webpack

2.文件解析

    -src

        -index.js  入口文件

//引入插件
import React from 'react'; 
import ReactDOM from 'react-dom'; 
	
//参数一:组件或者元素 
//参数二:目标容器 - 根节点
ReactDOM.render(<p>测试</P>,document.getElementById('root')) 
//底层原理: ReactDOM.render(React.creatElement('p',null,'测试'),document.getElementById('root'))

3.jsx

    (1)什么是jsx?

            jsx既不是字符串也不是 HTML,是一个 JavaScript 的语法扩展(虚拟DOM),在 JSX 语法中,你可以在大括号内放置任何有效的JavaScript 表达式Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用

     (2) jsx和HTML的区别是什么?

 

    下面两个例子是完全等效的

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

 

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

4.定义组件

     (1)什么是组件? - 组件就是具有独立功能的一个部分

     (2)如何定义一个reacrt的组件(js文件)

            1.工厂函数进行定义

 function MyComponent(){
    return <h2>工厂函数组件</h2>
}

         2.re6类组件进行定义 

       //引入核心依赖  react-dom只需要入口文件引入
  	   import React from 'react'
	   //引入css文件可直接使用 - webpack的原因,可以进行解析
	   import './test.css' 

	   //创建组件 - 类名 == 创建的文件名
	   class Hello extends React.Component {

		   //在prototype中
		   //组件内的方法推荐用箭头函数
		   show()=()=>{
			   //this为Hello的实例
			   console.log(this)
		   }

           //必须含有render
           //render函数就是返回一个jsx对象,当前组件的结构
		   //返回的 == vue的 template  虚拟DOM节点
		   render(){
			   return (
				   //this 是Hello的实例
				   <div  onClick = { this.show } className="test" style ={{color:"red"}}>hello word</div>

			   )
		   }
	   }

   注意:区别 - 类组件内可以有state属性

             vs插件 - ES7 React/Redux/GraphQL/React-Native snippets
                  rcc 快速进行创建js文件内容

  (3)列表渲染

       jsx可以自动渲染jsx数组( 数组里面的每一个元素都是JSX都是jsx对象)


	   import React, { Component } from 'react'

		const list = [
			{id:0,name:'张三',age:18},
			{id:1,name:'李四',age:12},
			{id:2,name:'王',age:20},
			{id:3,name:'张二三',age:32},
		]

		export default class Listcomp extends Component {
			render() {
				// map将返回的数据会自动装入数组中
				return (
					<div>
						<ul>
							{
								list.map((item,key)=>{
									return <li key={item.id}>我是{item.name},年纪:{item.age}</li>
								})
							}
						</ul>
					</div>
				)
			}
		}

  (4)插槽 - 渲染标签之间的内容 -    使用 this.props.children 

a.js
import Main from '路径',
<main>我是插槽之间内容</main>

b.js
render(){
   return (
      <div>this.props.children</div>
   )
}

 4.react中的属性

     (1)外部数据 - 属性 - props - 外部传值

//组件传值 - 与vue父传子的传值方式相同 属性名='传递的属性值'
import Hello from '路径'
<Hello name='aa'/>
	 


//接收值
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class Hello extends React.Component {
    
    //这个功能是插件完成,使用需下载插件yarn add prop-types
    static propTypes = {
             //key:value 
       name:PropTypes.string //规定外部传入的属性值必须是字符串
       
     }

	static defaultProps = {
		name:'默认名字' //自己设置外界传入属性的默认值
	}

	render(){
       //this.props.name 进行接收
		return (
			<div>{this.props.name}</div>
	 )
  }
		

     (2)内部数据 - state - 组件内使用数据

             定义: constructor里面定义
       

 constructor(){
       super();
       //定义数据
        this.state = {
            name:'张三'
           }  
        }


            constructor外面定义:
         

  state = {
      name:'张三'
   }


   使用: this.state.name

   修改:  

        this.setState({
               name:'李四' //注意为异步操作
           }) 

    例子:

    import React, { Component } from 'react'

    export default Astate extends Component{
            //state = {
               // name:'张三'
            //}

        constructor(props){
            super(props);
            //定义数据
            this.state = {
                name:'张三'
            }
        }
      
        //改为同步操作
        //  changeName = async ()=>{
        //   await this.setState({
        //        name:'李四'
        //    })
        // }

        changeName = ()=>{
           //修改数据 - 异步方法
           this.setState({
               name:'李四'
           },()=>{
               //回调函数中可以获取到变化后的name值
           })
        }
        console.log(this.state.name) //张三,setState是一个异步操作

        render(){
            return (
                <div>
                  我是:{this.state.name}
                  <button onClik={changeName}>修改名字</button>
                </div>
            )
        }
    }

  (3)refs属性

     案例 - 点击显示输入框文本,失去焦点显示输入框文本

class ShowInput extends React.Component{
      constructor(props){
          super(props);

          this.show = this.show.bind(this)
          this.handBlur = this.handBlur.bind(this)
      }

      show () {
         // alert(this.refs.content)
         alert(this.input.value)
      }

     //事件处理函数
      handBlur(e){
          alert(this.e.target.value)
      }

      render(){
          return ({
             // <input type='text' ref = 'content'> 废弃的写法
               <input type='text' ref = {input => this.input = input}>
               <button onClik={this.show}>提示输入</button>
               <input type='text' palceholder='失去焦点提示' onBlur ={this.handBlur}>
          })
      }
  }

 

5.生命周期

   (1)挂载阶段 - 
        //props表示外部传入的数据
        constructor(props){
            //初始化一些数据
        }
        

        componentWillMount(){
            //通知数据已经初始化好了,可以进行界面渲染了
            //不建议在这里发送接口,因为可能会执行多次
            // == vue的created
        }

        render(){
            //根据属性和状态渲染界面
            return ()
        }

        componentDidMount(){
            //通知组件已经挂载完成了 - 只会执行一次
            //发送请求,获取Dom,设置定时器或者延时器
            //== vue中的mounted
        }

 (2)运行阶段
      1.state的改变
      //状态改变是否要去更新界面,默认返回true,用于提升性能
      shuoldComponentUpdate(){
          return true
      }
      
      //新的数据已经准备好,可以渲染界面了
      componentWillUpdate(){ }

     //界面已经更新完了
      componentDidUpdate(){}

     2.prop的改变
      //属性改变是否去更新界面
      componentWillReceiveProps(newProps){
          //newProps修改后的数据,this.props 以前的数据
          console.log(newProps,this.props)
      }
      剩下和state一样
       
    
 
 (3)卸载阶段
     //通知组件即将销毁
     componentWillUnmount(){
         //清楚定时器延时器,解绑事件等等
     }

 生命周期图

   

5.表单组件

 (1)不受控表单组件

import React, { Component } from 'react'

export default class NoCotron extends Component {

    getValue = () =>{
      //1.利用原生js获取
     console.log(document.getElementById('input').value)
     //2.所有的ref都是存储在this.refs中的 this.refs - 都是Dom元素
     console.log(this.refs.inputs.value)
    }
    render() {
        return (
            <div>
                <input type="text" id="input" ref='inputs'></input>
                <button onClick={this.getValue}>获取text的值</button>
            </div>
        )
    }
}

(6) 受控表单组件 - 表单的值是被当前的自定义的组件的状态控制起来 -让表单值与state关联起来

import React, { Component } from 'react'

export default class Control extends Component {
    constructor(props) {
        super();
        this.state = {
            vals: 'xx'
        }
    }
    changeVal = (e) => {
        this.setState({
            vals: e.target.value
        })
    }
    getValues = () => {
        console.log(this.state.vals)
    }
    render() {
        //利用value,onChange进行对数据绑定为动态数据 == vue的v-modle
        return (
            <div>
                <input type="text" id="inputs" value={this.state.vals} onChange={this.changeVal}></input>
                <button onClick={this.getValues}>获取text的值</button>
            </div>
        )
    }
}

6.路由组件

    下载路由插件 - yarn add react-router-dom@4.3.0

     创建路由文件

import React, { Component } from 'react'
import { HashRouter, Switch, Route } from 'react-router-dom'
import Home from './Home'
import Login from './Login'
import Reg from './Reg'
import Error from './Error'

export default class Routes extends Component {
    render() {
        
        //注意: 从上到下,用了switch 后面会覆盖前面的
        //HashRouter - 容器组件
        //Switch 保证匹配到一个路劲就往下匹配
        //path-标识当前路径 component-当前路径匹配的组件  exact - 精准匹配
        return (
            <HashRouter>
                <Switch>
                    <Route path='/' exact component={Home}></Route>
                    <Route path='/login' component={Login}></Route>
                    <Route path='/reg' component={Reg}></Route>
                    <Route component={Error}></Route>  匹配所有的路径
                </Switch>
            </HashRouter>
        )
    }
}

  路由跳转

  跳转路由 - 标签跳转和js跳转
     import {Link} from 'react-router-dom'
     goToLogin = () =>{

         //js的方法实现跳转
         this.props.history.push('/login')
     }

     render(){
          return(<Link to='/login'>跳转到1登陆</Link>)  
     }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值