开始学习React.js(一)

先放一个react中文网站在这

先了解什么是虚拟Dom

虚拟dom就是程序员根据页面标签通过js创建dom树
之后通过新旧dom树进行对比,看dom树哪个部分变化,
从而只改变 改变的部分

  1. 虚拟dom本质就是用js对象来模拟dom元素和他们的嵌套关系
  2. 虚拟dom的目的就是为啦页面元素高效更新;也就是只更新改变的元素
  3. 虚拟DOM中所对比的时候用到啦diff算法;vue中也是diff

diff算法我理解大概就是,把js模拟的虚拟dom和原有的dom节点进行对比;把他们分为很多层级,每个层级和相应的层级对比;就比如一个树的最顶的树叶和另一个树的最顶的树叶对比,是一一对应的
具体解析可以看看阮一峰大神的文章

其次要懂得基本构建项目

cdn方法引入不推荐

 <!-- 加载 React。-->
  <!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"-->
  <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

// 使用JSX
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

npm 方法安装推荐 在这之前一定要确定你已经安装node环境

cnpm install -g create-react-app   // 安装react脚手架
cnpm i -g create-react-app   //install可以简写为i
// 创建项目
create-react-app 项目名称

// 我这里安装出错是因为没下载cnpm包,下载并同时设置淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org 

注意这里可能会报错,你可以试试以管理员模式下载 mac是sudo

初步认识React

ReactDom.render()传入两个函数,第一个是对象函数,也就是dom;第二个是dom需要显示的地方
react和vue的结构大相径庭;都是有静态资源和配置文件和node依赖等等;但是react的组件是.js形式所以我们要介绍重要的组成JSX

JSX

  • JSX是JavaScript XML,是React提供的Syntax Sugar, 能让我们可以在JS中写html标记语言。
  • JSX会把元素转换为js对象;但是每个元素必须要有一个根元素
let h = <h1>hello word</h1>  // 这是jsx语法
**let ph =	<h2>hello</h2> <p>word</p>**  // 会报错
let hp = <h2>hello <p>word</p></h2>  // 这样是对的 只能有一个根元素
  • JSX插值方法:{},{}中可以进行运算,函数,和变量
let word='hello word'
let h= <div>{word}</div> 
ReactDom.render(h,
document.getelementById('root')
)

React设置样式和类名

  • 设置类名是同样用插值方法,但是最好用className来设置(因为class在js中是关键字)如果有两个类名要在{}相加
//class.css 如下
.word{
  width:100%;
  height:200px;
  background:'blue'
}
.color{
color:'red'
}

//index.js
import './class.css'

let classname='word'
let div= <div className={'color'+word} ></div>
  • 在设置样式时和设置类名大相径庭,有些属性你不需要加px,react会自动帮你补全;但是backgroundColor复合单词拼成的属性,第二个单词首字母要大写;或者写成'background-color':'red'
  • 你也可以在style={}的{}中来写一个函数来判断你需要的样式也是没问题的
let backAndTextColor = {
    backgroundColor:'red',
    color:'white',
    fontSize:40
};
{/*  jsx中调用 */}
<div style={backAndTextColor}>看背景颜色和文字颜色</div>
{ /* 也可以在jsx中直接写样式,但是一定是对象格式 */ }
<div style={{backgroundColor:'red',color:'white',fontSize:40}}>看背景颜色和文字颜色</div>

React组件

  • react组件分为两种:类组件和函数组件(在ReactDom.render
    中,以大写字母的默认为组件)
  • 必须要有render () { return () } , render 中必须要有return
  • 组件之间可以互相嵌套
//函数组件

function Renders(props){
   console.log(props) // {hname:'哈哈哈哈'}    
  return (
    <div> Hello Word </div>
)
}
{ /* 简单的传值 */ }
ReactDom.render(<Renders  hname='哈哈哈哈' />,docment.getelementById('root'))

// 类组件
class Hello extends React.Component{
{/*  类组件必须有render函数 */}
     render(){  
       console.log(this)  {/*这里this是这个组件*/}
       return(
       <div>hello hi</div>
         )
      }
}

ReactDom.render(<Hello hi='hi' />,document.querySelector('#root'))

React state的认识

  • react的state和vue的data差不多都是用来储存模版中需要改变的变量;但是他们使用方法却不一样
class Clock extends React.component{
// construtor和super可以被省略不写,或者必须写全套
   constructor(props){  // es6语法 extends要配合constructor
      super(props);
      this.state={
         word:'hello'
      }  
   },
   render(){
   retrun(
    <div>{this.state.word}</div>
   )
 }
   
}

ReactDom.render(<Clock />,document.querySelector('#root'))
  • 当需要修改state中的变量时;需要用setState({})
  • setState是异步操作,不会立刻改变this.state,会等同步任务执行完,再去更新this.state

React父子组件传值

  • props父组件给子组件传值,子组件不可以修改父组件穿过去的值
class Parent extends React.component{
   constructor(props){ 
      super(props);
      this.state={
         word:'hello'
      }  
   },
   render(){
   retrun(
    <Chrild word={this.state.word} />
  )
 }
   
}
ReactDom.render(<Parent />,document.querySelector('#root'))


// 子组件
class Parent extends React.component{
   constructor(props){ 
      super(props); 
   },
   render(){
   retrun(
    <div>这是父组件传的值{this.props.word}</div>
   )
 }
   
}
  • 可以通过传递函数来实现子组件向父组件传值
//  父组件
class Parent extends React.component{
   constructor(props){ 
      super(props);
      this.state={
         word:'hello'
      }  
   },
   render(){
   retrun{
    <Chrild word={this.changeState} />
   }
 }
 // 也可以把下面函数改为箭头函数
 this.changeState=this.changeState.bind(this) 
 changeState(data){
   this.setState({
     word:data
  })
 }
   
}
ReactDom.render(<Parent />,document.querySelector('#root'))

// 子组件
class Parent extends React.component{
   constructor(props){ 
      super(props); 
      this.state={
      val:'888'
    }
   },
   render(){
   retrun(
    <div>
    这是父组件传的值{this.props.word}
    <p>改变父组件的值:{this.props.changeState(this.state.val).bind(this)}</p>
    </div>
   )
 }
   
}
  • React事件 都是用驼峰命名法onClick 而且react会把事件代理,你访问时需要在方法中e.event;例如阻止默认事件e.preventDefault()
  • 在事件的 {} 内可以写函数
<div onClick={(e)=>{this.setState({word:e})}}>
{/* 这两种都可以 */}
<div onClick={function(e){this.setState({word:e})}}.bind(this)>

React列表渲染和判断

  • React并没有vue的v-for和v-if等指令;所以判断就是考js来完成;

  • React的列表渲染就是你请求回来的数组;这里建议通过map方法来完成;也可以根据需求去选择其他方法

    这里是js循环方法的使用,可以看看

React 生命周期

  • 最先执行的是 construtor构造器
  • 之后componentWillMount 组件被载入之前 ;这里调用this.state不会引起组件重新渲染【这里的内容可以提到constructor中,所以很少使用】
  • 其次是componentDidMount 组件载入完成
  • 然后组件更新会使用shouldComponentupdate(nextProps, nextState)组件是否要被更新 使用布尔值来控制是否需要继续更新;nextProps 下一个props;nextState 指下一个state ; 我们可以用这个组件优化react;使其避免不必要的重复渲染
  • componentWillReceiveProps(nextprops) 当组件接受到新的props时触发;这个组件用于比较state中的值和nextprops是否一样,用不用重新赋值。
  • componentWillUpdate 组件更新前 ;这里render函数还未重新渲染
  • 之后render函数重新渲染
  • componentDidUpdate(prevProps,prevState)组件更新完成prevProps和prevState指组件更新前的props和state
  • componentWillUnmount()组件卸载前可以在这里清空定时器,清除挂载后手动创建的DOM,避免内存泄漏

React数据请求

React请求与vue大致一样,用axios请求就好啦;
axios中文网很细致,点击看看

React 插槽

  • 在react中没有插槽组件;如果想使用需要自己动手

父组件在子组件中传入的三个div,这三个div会默认通过props传到子组件中,然后我们在子组件中控制children的渲染即可

React路由

  1. 首先安装路由cnpm install react-router-dom --save
  2. Router标签:所有路由组件的跟组件,包裹路由规则的最外层容器
  3. Route标签:路由规则组件,显示当前规则对应路由
  4. Link标签:路由跳转组件
import {BrowserRouter as Router,Route,Link} from "react-router-dom";

<Router  basename='/acs'>  //basename设置此路由跟路径
    // link to传放置路由路径,也可以传一个对象
  <Link to={{path:'/main',seach:'?id=112'hash:'898i',state:{code:1}}}></Link>
  {/* */}
    // path:要跳转路径 ;exact精确模式,component:跳转的组件
  <Router path='/main'  exact component={Main}>
</Router>

// 之后接值需要在main组件的props
function Main(props){
  return(
   console.log(props.mactch)  // 在macth中
   )
}

  • link中可以加repalce,点击链接新地址将替换原来地址
  • 可以配合route标签完成动态路由
<Link to='main/123' >main</Link>
<Route path='main/:id' component={Main}></Route>

function Main(props){
  return(
   console.log(props.mactch.params)  // 在macth的params中
   )
}
  • Redirect组件和Switch路由组件
import {BrowserRouter as Router,Route,Link,Switch,Redirect} from "react-router-dom";
<Redirect to='/mian'></Redirect>  //路由重定向

<Router>
  <Switch>
     <Route path='/abc' exact component={Abc} ></Route>
     <Route path='/abc' exact component={Abc} ></Route>
  </Switch>
</Router>
// 如果没有switch, 即使有exact严格模式两个路由也都会执行,
// switch就是只执行一个路由
  • 我们还可以通过事件来跳转路由,
  • this.props.history.push('/',{id:'11'}) // 跳转到某个路由()中可以传参数;这种方式是在历史中新添加一个页面
  • this.props.history.replace('/',{id:'11'}) // 用 /替换当前页面;这种方式不会添加新页面;
  • this.props.history.go(1)// 前进一个页面
  • this.props.history.go(-1)// 后退一个页面

学习Redux

  • 安装reduxcnpm install redux --save
  • redux一般用于中大型项目,用来状态管理,用途解决组件互相通信;解决数据交互比较多的应用
  • store:数据仓库
  • state:state上一个对象;数据仓库所有数据都放在一个state里
  • action:一个动作,触发数据改变的方法action的type是必须值
  • dispatch:将动作触发成功方法
  • reducer:是一个函数,通过获取动作,改变数据,生成一个新的state
 // createStore是Redux的一个方法,Redux.createStore也可以
import {createStore} from 'redux' 

// 创建一个store ;reducer是一个函数用来改变数据
const store = createStore(reducer)
// state设置默认值,actipn是传入参数
const reducer=functiom(state={num:1},action){
   ...
   return state  // 返回新的state
}

store.dispatch({type:'add'})  //改变reducer函数的方法

store.getState()   // 获取store中state数据

store.subscribe(()=>{ // store中state数据改变时调用的函数

})

阮一峰的网络日志 ,看看大神会有更多收获

React-redux

  • 使用react-redux前提依然需要安装redux
  • 安装react-reduxcnpm install react-redux --save
import {createStore} from 'rudux'

import {Povider,connect} from 'react-redux'

// react-redux可以使用组件props和store进行传递数据

class Mycont extends React.component{
   rander(){
    const value=this.props.value;
    const onClickevent=this.props.onClickevent
  }

}

const store=creatStore(reducer)  //创建store
// ActionObj单独放需要改变state的方法 的对象
let ActionObj={
   change:function(state){
      state= state.toString()
      return state
   }
   ....其他方法
 }

// 创建reducer函数
const reducer=function(state={},action){
     state= ActionObj[action.type](action.另一个参数)
     ....其他操作
     return {...state}  // 结构方法
}
 //  创建链接state和props函数;**state行参是必须**
function mapStateToProps(state){
  return {
    value:state.num
 }
}
// 创建dispatch方法和props;**dispatch行参是必须**
function mapDispatchToProps(dispatch){
  return {
    onClickevent:()=>{dispatch()}
  }
}

// connect作用就是将两个方法映射在需要的组件中
const App=connect(
 mapStateToProps,
 mapDispatchToProps,
)(Mycont)  //(Mycont)是需要的组件

// Povider 组件自动将store的state和组件进行关联
ReactDom.render(
<Povider store={store}>
  <App />  {/* */}
  </Provider>,
  document.querySelector('#root')
)

Ant ui官网

你可能感兴趣的:(React,react)