react总结

react总结

特点

  1. 声明式的设计
  2. 高效,采用虚拟DOM来实现DOM的渲染,最大限度的减少DOM的操作
  3. 灵活,跟其他库灵活搭配使用(不包括VUE)
  4. JSX,js代码里写HTML,JavaScript语法的拓展
  5. 组件化、模块化
  6. 单向数据流,没有实现数据的双向绑定。数据->视图->事件->数据

一、创建项目

  1. 安装脚手架 create react app

    npm install -g create-react-app

  2. 创建项目

    create-react-app demo(项目名称)

    【补】npm run start / npm run build

二、JSX

  1. 优点:

    ​ (1)执行更快,框架将其编译为JavaScript代码时进行优化

    ​ (2)类型更安全,编译过程如果出错就不能编译,及时发现错误

    ​ (3)JSX编写模版更加简单快速(低于VUE)

    【注意】

    ​ (1)JSX必须要有根节点(有且只有一个)

    ​ (2)正常的普通HTML元素要小写,如果大写,默认认为是组件

  2. 结构

    (1) 由HTML元素构成

    (2)中间如果需要插入变量用{}

    (3){}中间可以使用表达式

    (4){}中间表达式可以使用JSX对象

    (5)属性和HTML内容一样都是{}来插入内容

    (6)标签必须闭合

    【补】

    (1)在JSX中使用JavaScript表达式,表达式写在花括号{}中,

    ReactDOM.render(
    	<div>
        	<h1>{1+1}</h1>
        </div>,
        document.getElementById('emp')
    )
    

    (2)React推荐使用内联样式,我们可以使用camelCase(小驼峰)语法设置内联样式,React会在指定元素数字后自动添加px

    [注]不用class,用className,因为class是js中的关键词

    var myStyle = {
        fontSize:100,
        color:'#FFFFFF'
    }
    ReactDOM.render(
    	<div>
        	<h1 style = {myStyle}>测试内容</h1>
        </div>
        ,
        document.getElementById('emp')
    )
    

    1》class style中,不可以存在多个class属性

    <div class="abc" class={'active'}></div>
    

    2》style样式中,如果存在多个单词的属性组合,第二个单词开始,首字母大写或者用引号

    borderBottom:'4px solid blue'
    

    3》多个类作用于同一个标签时

    1.
    <h1 className={color+" "+border}></h1>
    2.
    let test = [color,border].join(" ")
    <h1 className = {test}>hello world!</h1>
    

    (3)注释需要写在花括号中

    ReactDOM.render(
    	<div>
        	<h1>测试内容</h1>
            {/*注释......*/}
        </div>
        document.getElementById('emp')
    )
    

三、组件

组件首字母要大写

静态:没有交互事件内容的多用函数式组件

动态:一般会有交互或者数据修改的多用类组件,(类组件中可以定义函数)

  1. 函数式组件

    function HelloMessage(props){
        return <h1>hello world!</h1>
    }
    const element = <HellMessage></HellMessage>
    ReactDOM.render(
        element,
        document.getElementById('emp')
    )
    
  2. class组件

    class HellOMessage extends React.Component{
        render(){
            return <h1>hello world!</h1>
        }
    }
    ReactDOM.render(
        <HelloMessage></HelloMessage>,
        document.getElementById('emp')
    )
    
  3. 组件间数据传递

    Props-> 父传子,单向。可以为任意类型

    //-------------------- 父传子(props)------------------------------
    //父组件
    class Parents extends React.Component{
    	constructor(props) {
    	    super(props)
            this.state={
                isShow:false
            }
            this.changeShow = this.changeShow.bind(this);
            //changeShow写成箭头函数可以省去绑定
    	}
    	changeShow(){
    		this.setState({
    			isShow:!this.state.isShow
    		})
    	}   
    	render(){
    		//return返回JSX
    		return(
    			<div>
    				<h1>我是父组件</h1>
    				<button onClick={this.changeShow}>控制子组件是否显示</button>
    				<Children isShow={this.state.isShow}/>
    			</div>
    		)
    	}
    }
    //子组件
    class Children extends React.Component{
    	constructor(props) {
    	    super(props)
    	    this.state={
    				
    			}
    	}
    	render(){
    		//return返回JSX
    		console.log(this.props.isShow)
    		let myStyle = null
    		if(this.props.isShow){
    			myStyle = 'item'+' '+'active'
    		}else{
    			myStyle = 'item'
    		}
    		return(
    			<div className={myStyle}>
    				<h1>我是子组件</h1>
    			</div>
    		)
    	}
    }
    

    调用父元素的函数操作父元素的元素,从而实现数据从子元素传递到父元素

    class Parent1 extends React.Component{
    	constructor(props) {
    	    super(props)
            this.state = {
                childrenMsg:null
            }
    	}
    	getMsg=(data)=>{
    		// console.log(this.props)
    		console.log(data)
    		this.setState({
    			childrenMsg : data
    		})
    	}
    	render(){
    		//return返回JSX<--用于将父元素的函数传递给子元素-->
    		return(
    			<div>
    				<h1>我是子组件传递的内容:{this.state.childrenMsg}</h1>
    				<Children1 getMsg={this.getMsg} />	
    			</div>
    		)
    	}
    }
    class Children1 extends React.Component{
    	constructor(props) {
    	    super(props)
            this.state={
                message:'我是子组件内容'
            }
    	}
    	sendMsg=()=>{
    		console.log(this.props)
    		// 错误
    		// this.setState({
    		// 	message:'我是传递内容'
    		// })
    		//将子元素传递给父元素,实际就是调用父元素传递进来的父元素函数
    		this.props.getMsg(this.state.message)
    	}
    	render(){
    		//return返回JSX
    		return(
    			<div>
    				<button onClick={this.sendMsg}>获取子组件内容</button>
    				<button onClick={()=>{this.props.getMsg(this.state.message)}}>获取子组件内容</button>
    			</div>
    		)
    	}
    }
    

四、State

State(状态)类似于Vue的data

  1. constructor(props)构造函数

    如果初始化state或者不进行方法绑定,则不需要为React组件实现构造函数

    其他语句之前调用super(props)

    构造函数主要用于:

    1》通过 this.state 赋值对象来初始化内部state。(类似于vue的data)

    this.state = {count : 0};
    

    【注】只能在构造函数中直接为 this.state 赋值,其他方法中用 this.setState({ }) 赋值

    2》为事件处理函数绑定实例

    this.handleClick = this.handleClick.bind(this)
    
constructor(props){
    super(props);
    this.state = {
        counter: 0
    };
    this.handleClick = this.handleClick.bind(this)
}
  1. static getDerivedStateFormProps(props, state)

    在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。

  2. render()方法是class组件中唯一必须实现的方法

    检查 this.propsthis.state 的变化

  3. componentDidMount()组件挂载后

五、事件

  1. React事件命名采用小驼峰(camelCase)

  2. 传入函数必须用***{}*** 括起来

  3. 事件对象:React返回的事件对象是代理的原生的事件对象,如果想要查看事件对象的具体值,必须直接输出事件对象的属性

    <button onClick = {changeShow}>点一下</button>
    

    【注意】

    1》阻止默认行为

    /*传统HTML*/
    <form οnsubmit="console.log('You clicked submit.'); return false">
      <button type="submit">Submit</button>
    </form>
    
    /* React中*/
    function Form() {
      function handleSubmit(e) {
        e.preventDefault();
        console.log('You clicked submit.');
      }
    
      return (
        <form onSubmit={handleSubmit}>
          <button type="submit">Submit</button>
        </form>
      );
    }
        
    
    

    2》事件传参

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

    【注意】

    class的方法不想在构造函数constructor中绑定解决方法

    1. class fields写法(public class fields)

      class LoggingButton extends React.Component {
        // 此语法确保 `handleClick` 内的 `this` 已被绑定。
        // 注意: 这是 *实验性* 语法。
        handleClick = () => {
          console.log('this is:', this);
        }
        render() {
          return (
            <button onClick={this.handleClick}>
              Click me
            </button>
          );
        }
      }
      
      
    2. 箭头函数

      class LoggingButton extends React.Component {
        handleClick() {
          console.log('this is:', this);
        }
        render() {
          // 此语法确保 `handleClick` 内的 `this` 已被绑定。
          return (
            <button onClick={() => this.handleClick()}>
              Click me
            </button>
          );
        }
      }
      

六、条件渲染

JavaScript运算符 if 条件运算符 (例如:三元运算 &&)

  1. 使用js中的if条件语句判断

  2. 与运算符(&&)

    {unreadMessages.length>0 && <h2>You have {unreadMessages.length} unread messages</h2>}
    
    //因为在JavaScript中,true && expression 总是返回expression,而false && expression 总是返回 false
    
  3. 三目运算符

  4. 阻止组件渲染

    render 方法直接返回null,不进行任何渲染

七、列表渲染

  1. JSX模式

    将列表内容拼装成数组放置到模版中,将数据拼装成数组的JSX对象使用***{}*** 在JSX内构建一个元素集合。使用数组的map方法,对每一项数据按照JSX的形式进行加工,最终到一个每一项都是JSX对象的数组,再将数组渲染到模板中

    const numbers = [1,2,3,4,5]
    const listItems = numbers.map((item)=>{
        return <li>{item}</li>
    })
    ReactDOM.render(
    	<ul>{listItem}</ul>,
        document.getElementById('emp')
    )
    
  2. 组件模式

    key值需要放置到每一项中

    在map方法中的元素需要设置key属性

    function NumberList(props){
        const numbers = props.numbers;
        const listItems = numbers.map(item=>{
            <li key={item.toString()}>{item}</li>
        })
        
        return (
        	<ul>{listItems}</ul>
        )
    }
    const numbers = [1,2,3,4,5]
    ReactDOM.render(
    	<NumberList numbers={numbers}/>,
        document.getElementById('emp')
    )
    

八、插槽

九、路由

安装 npm install react-router-dom

ReactRouter三大组件
  1. Router:所有路由由组件的根组件(底层组件),包裹路由规则的最外层容器;

    属性:basename->设置理由根路径

    ​ router->可以在一个组件中写多个

    <Router>
       <div>
          <Link to="/config">ceshi</Link>
       </div>
    </Router>
    
  2. Route:路由规则匹配组件,显示当前规则对应的组件

    【注】若要精确匹配,需要在route上设置exact属性,不加就还是模糊匹配

     <Route  path="/config" component={Config} exact></Route>
    
    
  3. Link:路由跳转的组件

    (1)可以设置属性进行页面的跳转,to属性可以直接写路径的字符串,也可以通过对象进行路径的设置

    ​ {[pathname] 跳转的路径 [search] get请求的参数[state]传入的数据}

    class test extends React.Component{
        constructor(props){
            super(props)
        }
        render(h){
            let obj = {pathname:'/config',search:'123',state:true,a:'789'}
            return (
            	<Router>
                	<div>
                    	<Link to={obj}></Link>
                    </div>
                </Router>
                <Route  path="/config" component={Config}></Route>
            )
        }
    }
    

    (2)Replace点击链接后新地址将历史记录的原地址替换,动态路由通过***props.match.params.参数*** 获取

    constructor(props){
        super(props)
        console.log(props.match.params.参数名)
    }
    

重定向组件

如果访问某组件时,有重定向组件,那么就会修改页面路径,使得页面内容显示为重定向路径的内容

<Redirect to="/about"></Redirect>

Switch组件

让switch组件内容的route只匹配一个,只要匹配到了,剩余的路由规则将不再匹配

<Switch>
	<route></route>
    <route></route>
</Switch>

JS实现跳转

利用history中的***push*** replace 等属性进行跳转

goToPage=(e)=>{
	if(this.props.location.state){
		this.props.history.push("/home")
	}else{
		this.props.history.push("/message/chanshu")
	}
}
路由传参
  1. params传参

    <Link to={`/home/${name}/${age}`}></Link>
    <Route path="/home/:name/:age" component={home}></Route>
    在home组件的props.match.params获取
    
  2. search传参

    <Link to={`/home?name=${name}&age=${age}`}></Link>
    <Route path="/home" component={home}></Route>
    
    import qs from 'querystring'
    qs.paese(this.props.location.search.slice(1))
    
  3. state参数

    <Link to="{pathname:'/home',state:{name:'123',age:18}}"></Link>
    <Route path="/home" component={home}></Route>
    this.props.location.state
    
withrouter

可以加工一般组件,让一般组件具备路由组件特有的API

import React,{Component} from 'react'
import {withRouter} from 'react-router-dom'
class Header extends Component{}
export default withRouter(Header)

十、状态管理 Redux

store:数据仓库,保存数据的地方

State:一个对象,数据仓库里的所有数据放到一个state里

Action:一个动作,触发数据改变的方法

Dispatch:将动作触发成方法

Reducer:一个函数,通过获取动作,改变数据,生成一个新的state,从而改变页面

  1. 安装

    npm install redux -save

  2. 流程

    1》初始化数据:创建一个*reducer(state={obj},action)*** 函数用于生成一个新的state(注意结构解析***{…state}***的使用),state用于存放数据,action接收dispatch传递的参数;

    Reducer作用:初始化数据;通过获取动作,改变数据

    const reducer = function(state={num:0},action){
    	switch(action.type){
    		case "add":
    		state.num++;
    		break;
    		case "reduce":
    		state.num--;
    		break;
    	}
    	return {...state}
    	console.log(store.getState())
    }
    

    2》创建仓库:***createStore(reducer)***,从Redux中引入

    import {createStore} from 'redux'
    var store = createStore(reducer)
    

    3》修改数据:创建修改函数,调用***store.dispatch({条件或名称,参数})***向render传递参数。

    其实就是***store.dispatch(Action)***,Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置,社区有一个规范可以参考。

    const add = function(){
    	store.dispatch({type:'add',status:1})
    	console.log(store.getState())
    }
    const reduce = function(){
    	store.dispatch({type:'reduce',status:1})
    }
    

    4》获取数据:store.getState().name

    5》修改视图:***store.subscribe()***监听数据变化

    store.subscribe(()=>{
    		ReactDOM.render(
    		<div>
    			<h1>结果为{store.getState().num}</h1>
    			<button onClick={add}>+</button>
    			<button onClick={reduce}>-</button>
    		</div>,
    		document.getElementById('emp')
    		)
    	}
    )
    

十一、React-redux

​ 将所有组件分成UI组件容器组件

  1. 安装

    npm install react-redux -save

  2. 详情

    1》connect() 将组件和数据(方法)进行连接

    import {connect} from 'react-redux'
    const VisibleTodoList = connect(
    	mapStateToProps,
        mapDispatchToProps
    )(TodoList)
    

    VisibleTodoList是connect方法生成的容器组件,TodoList是UI组件,mapStateToProps负责输入逻辑,即将state映射到 UI 组件的参数(props),mapDispatchToProps负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

    2》mapStateToProps 这个函数用于将store的state映射到组件里的props

    3》mapDispatchToProps 将store中的dispatch映射到组件的props里,实现方法的共享

    4》Provider组件 自动将store里的state和组件进行关联

    ReactDOM.render(
        <Provider store={store}>
          <TodoList></TodoList>
        </Provider>,
        document.getElementById('emp')
    )
    

生命周期

打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值