【总结】React

一、搭建环境

(安装过yarn之后,它会根据yarn来自动创建项目   cnpm install -g yarn)

  1. 安装脚手架:npm install -g create-react-app  
  2. 创建项目 :Create-react-app 项目名称     
  3. 运行:npm run start(或yarn start)  构建:npm run build(或yarn build)

快速搭建:npx create-react-app 项目名称  (1、安装脚手架2、创建项目3、删除create-react-app工具)(使用条件:node版本大于6,npm版本大于5.2)

二、React目录结构  React创建组件、 ReactJSX语法、 React绑定数据 React绑定对象 、React绑定属性( 绑定class  绑定style 图片)

manifest.json 文件简介:(不用管)

https://lavas.baidu.com/mip/doc/engage-retain-users/add-to-home-screen/introduction
index.js 入口文件

//React是React的核心库
//react-dom.js是提供与DOM相关的功能
import React from 'react';
import ReactDOM from 'react-dom';
//公共样式(拿到项目把css删掉即可)
import './index.css';
//组件
import App from './App';

//不用管,加快react运行速度的一个js文件
import * as serviceWorker from './serviceWorker';

//把APP这个节点渲染到root这个节点上
ReactDOM.render(<App />, document.getElementById('root'));

//加速的
serviceWorker.unregister();

root在index.html中,意思是在root这个节点下,引入App组件

一般进入src目录以后

新建components目录(放组件)

新建assets目录(放静态文件)  下面再新建images目录和css目录  (改下路径)

import React, { Component } from 'react';
import logo from './assets/images/logo.svg';
import './assets/css/App.css';

class App extends Component {
  //jsx:html和js的混写模式
  //render 模板
  render() {
    return (
      <div className="App">
        根组件
      </div>
    );
  }
}

export default App;

创建子组件挂载在根组件上

在components里创建Home.js(组件文件名称首字母大写,组件类名也要首字母大写)

import React,{ Component } from "react";
export default class Home extends Component{
    constructor(){
        super();
        this.state={
            name:"张三"
        }
    }
    render(){
        return(
            <div>
                你好{this.state.name}
            </div>
        )
    }
}

在APP.js中引入

import Home from "./components/Home";
<Home/>

构造函数constructor里面必须有super()

在构造函数constructor中定义该组件的参数:this.state={ key:value}

另一种写法:

import React from "react";
class News extends React.Component{
}

等于
import React,{Component} from "react";
class News extends Component{
}

Es6中的super可以用在类的继承中,super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

官方文档写法:

constructor(props){
    super(props);//用于父子组件传值
}

只有一个理由需要传递props作为super()的参数,那就是你需要在构造函数内使用this.props

官方提供学习的例子中都是写成super(props),所以说写成super(props)是完全没问题的,也建议就直接这样写。

绑定属性注意:
      class 要变成 className   

      for 要变成  htmlFor    (label中这个for中值如果和Input的id一样,点击label就会在input中获取焦点)

      style属性和以前的写法有些不一样

<div style={{'color':'blue'}}>{this.state.title}</div>
<div style={{'color':this.state.color}}>{this.state.title}</div>

其它的都一样

import React,{ Component } from "react";
import "../assets/css/home.css"
export default class Home extends Component{
    constructor(props){
        super(props);
        this.state={
            name:"张三",
            title:"我是一个title",
            color:'red',
            style:{
                color:'red'
            }
        }
    }
    render(){
        return(
            <div>
                你好{this.state.name}
                <div title={this.state.title}>title竟然是个指令</div>
                <div className="red">红色</div>
                <div className={this.state.color}>这样也可以红色</div>
                <div style={{"color":'red'}}>行内样式</div>
                <div style={this.state.style}>另一种行内样式写法</div>
                <label htmlFor="name">姓名</label>
                <input type="text" id="name"/>
            </div>
        )
    }
}

引入图片:必须通过模块化的形式

最上面import logo from "../assets/images/image.png";

           <img src={logo}/>

另一种ES5的方法    <img src={require(“../assets/images/image.png”)}/>

远程图片直接引入即可

渲染数组(循环):

什么都不加就可以直接显示出来,还可以循环dom元素,还可以把数组转成dom数组,用map

循环DOM数据要加key(不会影响什么,但会报错,在DOM数组定义的时候就要加key)

import React,{ Component } from "react";
import "../assets/css/home.css";
export default class Home extends Component{
    constructor(props){
        super(props);
        this.state={
            list:[<h2 key="1">我是一个H2标签</h2>,<h3 key="2">我是一个h3标签</h3>],
            list2:['12111','2222','333232323'],
            list3:[
                {title:"123123123"},
                {title:"456456456"},
                ]
        }
    }
    render(){
        var lResult=this.state.list2.map(function(value,key){
            return <li key={key}>{value}</li>
        })
        return(
            <div>
                {this.state.list}
                {this.state.list2}
                {lResult}
                {
                    this.state.list3.map((function(value,key){
                        return <li key={key}>{value.title}</li>
                        //return里面是多行就加()
                    }))
                }
            </div>
        )
    }
}


三、事件和方法

定义方法:和construct和render平级(不需要有逗号)

run(){
    alert("123");
}
render(){
    return(    
        <div>
            <button onClick={this.run}></button>
        </div>
    )
}

如果想在方法中调用this.state定义的参数  如果直接this.state.参数是不行的

run(){
    alert(this.state.data);//是不行的,因为当前的this不是指向我们要的this
}

方法1:方法中传参:

run(){
    alert(this.state.data);
}
render(){
    return(    
        <div>
            <button onClick={this.run.bind(this.state)}></button>
        </div>
    )
}

方法2:在构造函数中传参:

constructor(props){
    super(props);
    this.run=this.run.bind(this.state);
}
run(){
    console.log(this.state.data);
}
render(){
    return(
        <div>
            <button onClick={this.run}></button>
        </div>
    )
}

方法3:箭头函数(好用)

run=()=>{
    alert(this.state.data);
}
render(){
    return(
        <div>
            <button onClick={this.run}></button>
        </div>
    )
}

想在方法中改变state的值:用上面三种方法改变this

然后this.setData({key:value})即可

 

在方法中传值改变this.setData

<button onClick={this.run("张三")}></button>  //会报错,因为this没有指向想要的this

必须<button onClick={this.run(bind(this),"张三")}>

 

方法中传参第一个参数一定是this
1、方法中传值——传的是state中定义的参数

<button onClick={this.runG.bind(this,this.state.changeName)}>方法中</button>

 runG=(msg)=>{
        this.state.name=msg
        alert(this.state.name)
    }

或者直接不在html中加参数,因为方法中可以直接用this.state.参数

<button onClick={this.runH}>方法中</button>
runH=()=>{
        this.state.name=this.state.changeName;
        alert(this.state.name)
    }

2、方法中传值——传的不是state中定义的参数
在方法中传递参数,不管是否用ES6箭头函数,都要this.方法.bind(this)

<button onClick={this.runE.bind(this,"hi")}>方法中</button>

<button onClick={this.runF.bind(this,"nihao")}>方法中</button>

 runE=(msg)=>{
        this.state.name=msg
        alert(this.state.name)
    }
    runF(msg){
        this.state.name=msg
        alert(this.state.name)
    }


事件对象、键盘事件、表单事件、ref获取dom节点、React实现类似vue双向数据绑定

事件对象:在出发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息

直接在方法中打印event即可

<button onClick={this.run}></button>

run=(event)=>{

    console.log(event);  //包含着所有与事件有关的信息

最大作用;获取dom节点

console.log(event)

console.log(event.target);  //获取执行事件的dom节点    获取到点击的button按钮

改变DOM的属性

event.target.style.background='red';

(小程序里无法传值,所以要用自定义属性来传值)

<button onClick={this.run}></button>

run=(event)=>{

    console.log(event);  //包含着所有与事件有关的信息

 

react里面没有提供双向数据绑定
表单事件

点击Button以后获取input中的值
方法一:使用Input的onChange事件和button的onClick事件
1、监听表单的改变事件
2、在改变的事件里面获取表单输入的值
3、把表单输入的值赋值给username
4、点击按钮的时候获取state里面的username

constructor(props){
    super(props);
    this.state={
        username:""
    }
}

inputChange=(event)=>{
    this.setState({
        username:event.target.value
    })
}
getInput=()=>{
    alert(this.state.username)  
}
render(){
    return(
        <input onChange={this.inputChange}/>
        <button onClick={this.getInput}></button>
    )
}


方法二:ref获取dom节点(替换了使用event.target.value获取input的值)
<input onChange={this.inputChange} ref="username"/>
inputChange=()=>{
    let val=this.refs.username.value;
}

 

键盘事件onKeyUp和onKeyDown (e.keyCode)
inputKeyUp=(e)=>{
    console.log(e.keyCode)
    回车
    if(e.keyCode==13){
        alert(e.target.value)
    }
}
<input onKeyUp={this.inputKeyUp}/>

 

 

双向数据绑定:model改变影响view,view改变影响model(vue中v-model,angular中ng-model,react中没有,react不是mvvm框架)

constructor(props){
    super(props)
    this.state={
        username:"123"
    }
}
<input value={{this.state.username}}/>        //model层影响view,如果只是写value,不写onChange会报错,得写成defaultValue
<input defaultValue={{this.state.username}}/>   


双向数据绑定:
inputChange=(e)=>{
    this.setState({
        username:e.target.value
    })
}

mvvm:  m改变影响v,this.state={name:"xxx"}; 给input框绑定这个name;

             v改变影响m,给input框绑定onChange事件,只要input中的value改变,就将这个改变值this.setState绑定给m层

 

约束性和非约束性组件:
非约束性:<input type="text" defaultValue="a"/>  这个defaultValue其实就是原生DOM中的value属性(是写死的)
约束性: <input value={{this.state.username}} onChange={this.inputChange}/>这里的value属性不再是一个写死的值,
constructor(props){
    super(props);
    this.state={
        name:"",
        sex:1,
        citys:["","",""],
        city:"",
        hobbys:[{checked:true,title:""},{checked:false,title:""},{checked:false,title:""}],
        hobby:""
    }
}

inputChange=(e)=>{
    this.setState({
        username:e.target.value
    })
}
submit=(e)=>{
    //先阻止form中的submit的默认刷新事件
    e.preventDefault();
    console.log(this.state.name,this.state.sex,this.state.city)
    
}
handelSex=(e)=>{
    this.setState={
        sex:e.target.value
    }
}
handleCity=(e)=>{
    this.setState={
        city:e.target.value
    }
}
<form onSubmit={this.submit}>
    用户名:<input value={{this.state.username}} onChange={this.inputChange}/><br/><br/>
    性别:男<input tyoe="radio" value="1" checked={this.state.sex==1} onChange={this.handelSex}/>
          女<input tyoe="radio" value="2" checked={this.state.sex==2} onChange={this.handelSex}/>    
    居住城市:(下拉框 循环)
        <select value={this.state.city} onChange={this.handleCity}>
            {
                this.state.citys.map(function(value,key){
                    return <option key={key}>{value}</option>    
                })
            }            
        </select>
    爱好:{
        this.state.hobbys.map(function(value,key){
            return (
                <div>
                    {value.title}<input type="checkbox" checked={value.checked}/>
                </div>
                只要是return()中,就需要用div根元素把子元素包起来
            )
        })
        
          }
    <input value="提交" type="submit"/>
</form>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值