react.js+jsx+route+redux+mockjs+axios 联合学习全笔记 入门教程

首先如果是新项目 最好使用
react脚手架 create-react-app 简单方便干净。
该文章地址:https://blog.csdn.net/qtfying/article/details/78665664

引入react框架

1,直接在网页引入

<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js">script>

<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js">script>

<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js">script>
2,在webpack中引入

先安装npm install –save react react-dom

import React from 'react'
import ReactDOM from 'react-dom'

渲染页面

import React from 'react'
import ReactDOM from 'react-dom'
//react渲染方法
ReactDOM.render(
    //jsx写法的html元素
    

Hello, world!

, //渲染目标元素 document.getElementById('area') )

元素

创建一个网页元素

//创建一个元素element
let element = 

Hello,element!

//element元素可以在render()直接中渲染 ReactDOM.render( element, document.getElementById('root') ); //element元素可以在组件中调用 class Hello extends React.Component { render(){ return (
    {listItems}
); } }

组件

创建一个函数组件
function Hello(props) {
  return 

Hello, {props.name}

; }
创建一个类组件
//创建组件需要创建一个类,类名必须首字母大写,必须继承React.Component并实现render()方法
class Hello extends React.Component {
    render() {
        return 

Hello, world!

//这里可以直接返回元素element //return element } }
渲染组件
//将组件类名按html形式写在render方法中即可在页面中看到
ReactDOM.render(, document.getElementById('root'))
组件相互调用
//组件A
class HelloA extends React.Component {
    render() {
        return 

this is A

} } //组件B调用组件A class HelloB extends React.Component { render() { return ( <div>

this is B

//此处调用组件A div> ) } }
元素调用组件
const element = ;
组件传值

父组件通过属性的方式传值给子组件

class HelloA extends React.Component {
    render() {
        return (
            //此时组件HelloA 获得attr的值
            'fuck'/>
        )
    }
}

子组件获取值

class HelloA extends React.Component {
    render() {
        //得到父组件传来的attr值
        return 

this is A {this.props.attr}

} }
值验证

引入PropType库,验证值,避免错误。

import PropTypes from 'prop-types'
MyComponent.propTypes = {
  // 你可以将属性声明为以下 JS 原生类型
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,
  }
//详情:[https://doc.react-china.org/docs/typechecking-with-

在组件中使用

//新建组件类
class Test extends Component {
    //验证属性'name'为字符串,并且不为空
  static propTypes = {
      name: PropTypes.string.isRequired
  }
  //渲染
  render() {
      return (
          <div className='aaa'>
              

'tes'>{this.props.name}

div> ) } }

组件的状态与生命周期

1,状态state与生命周期只能应用于用类创建的组件上。不能应用与方法创建的组件上
2,状态state的初始化需要用es6类的构造函数。

class NewComponent extends React.Component {
    //constructor是es6类的构造方法。props父级调用该组件时传递的属性数据
    constructor(props) {
        //super()方法是子类继承父类必要条件
        super(props);
        //将date赋予state  this.state只能在constructor初始化
        this.state = {date: new Date()};
    }
    //自定义方法
    change() {
        //该方法用于更新state状态,只有通过该方法,才会重新渲染
        this.setState({
             date: new Date()
        });
    }
    //渲染
    render() {
        return (
            

Hello, world!{this.state.date}

); } //钩子函数 当虚拟dom挂在到网页dom上时立即执行 componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } //钩子函数 当前dom即将从网页dom卸载时执行 componentWillUnmount() { clearInterval(this.timerID); } }

事件

在react+jsx中 事件名用驼峰写法。并且方法用中括号表示
避免被短时间内触发太多次事件的方法控制调用


<button onclick='someFun()'   />

<button onClick={someFun}   />

事件方法默认无法被绑定到this上,以下几种方法可以解决
1,在组件类的构造函数中绑定

    //在构造函数中绑定
    constructor(props) {
        super(props)
        this.clickFunc = this.clickFunc.bind(this)
        console.dir(this)
    }
    //只有绑定才能获取到this
    clickFunc(){
        console.dir(this)
    }

2,在调用时使用回调

3,将事件方法使用箭头函数写法(需要属性初始化器语法开启)

    clickFunc=(e)=>{
        //事件可以通过e获取参数
        console.info(e.target.value)
        console.dir(this)
    }

事件传值

//首先创建方法接受参数
handleClick(index, e) {
        console.info(index)
        // e.preventDefault()]
    }

    render() {
    //使用箭头函数传值。如果使用普通写法,函数会立即执行。
        

列表

元素方式

let list=[3, 1, 2, 44]
let ListItem=list.map(
    //key是唯一标示,x是
    (number, index) => 

{number}

)

jsx嵌入方式

<ul>
    {list.map((number) =>
        <ListItem key={number.toString()}
             value={number} />
    )}
ul>

表单

所谓的受控组件,就是react实现表单的双向绑定,只不过它实现的比较复杂。。。。。

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    //初始化状态
    this.state = {value: ''};
    //绑定事件
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
    //值变动事件
  handleChange(event) {
    this.setState({value: event.target.value});
  }
    //提交事件
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      
this.handleSubmit}> type="submit" value="Submit" />
); } }

元素组合

a组件调用b组件就是继承

class A extends React.Component {
    render(){
        return <div><div>
    }   
}
class B extends React.Component {
    render(){
        return 
   }
}

那么如果这时组件B需要将元素嵌入到组件A中呢,这时就需要props.children 相当于(VUEJS中到继承)

class A extends React.Component {
    render(){
        return <div>
                //从外部内嵌到元素位置
                {props.children}
        <div>
    }   
}
class B extends React.Component {
    render(){
        return 
            //在此处内嵌
            

fuck u

} }

状态提升

跨组件调用状态时,父组件通过属性传递到方式 将state与setSate传递给 子组件到props中。子组件发生变化立即更新props传过来到state,达成了状态提升与同步。

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};
  }

  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }

  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});
  }

  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;
    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;

    return (
      <div>
        "c"
          //子组件到值来自父组件传递
          temperature={celsius}
          //子组件发生变化更新父组件到 setState控制方法
          onTemperatureChange={this.handleCelsiusChange} />

        "f"
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} />

        

      div>
    );
  }
}

直接修改dom元素

vue中有相同到东西。但用着方便多类。在react中它只能对class声明对对象使用。

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // 创建 ref 存储 textInput DOM 元素
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:通过 "current" 取得 DOM 节点
    this.textInput.current.focus();
  }

  render() {
    // 告诉 React 我们想把  ref 关联到构造器里创建的 `textInput` 上
    return (
      <div>
        "text"
          ref={this.textInput}} />

        "button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      div>
    );
  }
}

Context跨组件传值

当组件a包含组件b,组件b又包含组件c时,如果从a向c传值,就要先传到b,再从b传到c。而使用context就可以直接一步从a传到c
(不要仅仅为了避免在几个层级下的组件传递 props 而使用 context,它是被用于在多个层级的多个组件需要访问相同数据的情景。)

// 创建一个 theme Context,  默认 theme 的值为 light
const ThemeContext = React.createContext('light');

function ThemedButton(props) {
  // ThemedButton 组件从 context 接收 theme
  return (
    
      {theme => 

不被渲染到包裹标签Fragments

有些时候你要返回一个多元素集合,但react只允许你返回一个包含子标签的单个元素,有时我们并不希望这个外部包裹元素被渲染出来,这时可以使用空标签

class Columns extends React.Component {
  render() {
    return (
      <>
        Hello
        World
      
    );
  }
}

需要key的时候使用React.Fragment

class Columns extends React.Component {
  render() {
    return (
      
        Hello
        World
      
    );
  }
}

将元素插入到现有dom节点的方法Portals

render() {
    //将this.props.children渲染到制定到domNode上
  return ReactDOM.createPortal(
    this.props.child欧ren,
    domNode,
  );
}

路由

前端路由是单页应用到重要条件。根据不同的访问地址来调取不同到组件显示,而不必刷新这个页面。
react-router中文文档
react-router-dom4简约教程

//安装路由
npm install --save react-router-dom
//引入模块
import {
    //Router就是个容器。触发route功能都需要在Route标签中。而且只能有一个子标签。
    //模仿正常都地址
    BrowserRouter,
    //地址中有#符号
    HashRouter,
    //受link控制的 装载组件的容器
    Route,
    //普通的跳转工具
    Link,
    //API比较多的跳转工具
    NavLink
} from 'react-router-dom'

两个组件

class About extends React.Component {
    render() {
        return (
            <div> about div>
        )
    }
}
class Contact extends React.Component {
    render() {
        return (
            <div> contack div>
        )
    }
}

主组件

export default class IndexPage extends Component {
    render() {
        return (
            //路由容器,basname设置基础path
            '/home'>
                //只能有一个子
                <div>
                    //组件容器。path设置匹配地址,component设置匹配组件。
                    '/about' component={About} />
                    '/contact' component={Contact} />
                    //链接按钮。相当于a标签
                    'about'>about
                    'contact'>contact
                div>
            
        )
    }
}

发起数据请求(ajax访问服务器)

使用ajax库

可以使用自己喜欢的 AJAX 库,如jQuery AJAX 和浏览器内置的 window.fetch。 值得一提的是Axios,目前被vue官方宣传使用,傻瓜操作,完美的跨域解决方案,值得拥有。

在何处使用

数据请求应该在componentDidMount 生命周期方法内发送。这样你才能够在请求的数据到达时使用 setState 更新你的组件。应该在componentWillUnmount生命周期内取消请求

1.使用window.fetch方法

window.fetch的方法贴

fetch('sdf.json地址', {
            // 是否允许跨域带cockie
            credentials: 'include',
            //请求头
            headers: {
                'Accept': 'application/json'
            },
            //方法
            method: 'get'
        }).then(res => res).then(
                //获取结果
                (result) => {
                    this.setState({
                        list: result.list.id
                    })
                },
                //捕获错误
                (error) => {
                    this.setState({
                        error
                    })
                }
            )
2.使用jquery ajax
$.ajax({
    url:'http://www.bai.com',
    type:"DELETE",
    data:{
        id:1//假设需要删除id=1的数据
    },
    dataType:'json',
    success:function(e){
        console.log(e)
    }
})

3.重点推荐axios

npm地址含教程

        //假数据,可以拦截请求,用于前端测试,后面有介绍
        Mock.mock(
            /\.json/,
            'get',
            // 属性 list 的值是一个数组,其中含有 1 到 10 个元素
            {
              'age|20-30':25
            }
        )
        //发起请求
        Axios({
            //方法,restfull
            method: 'get',
            //地址
            url: 'asdf.json',
            //返回格式
            responseType: 'json'
        }).then(function(response) {
            //结果
            console.dir(response.data)
        })

axios取消请求的方法

数据mockjs

示例的 API 返回的 JSON 对象使用mock生成,mock可以拦截ajax请求,返回加数据,便于前端调试。

安装mockjs

git地址,里面有配置教程

npm i mockjs

配置

var Mock = require('mockjs')
var data = Mock.mock(
    //期望被拦截的地址。当你的react请求这个地址时就会返回我们的加数据
    /\.json/,
    'get',
     // 属性 list 的值是一个数组,其中含有 1 到 10 个元素
     {
        'age|20-30':25
     }
)
// 输出结果
console.log(JSON.stringify(data, null, 4))
随机数据
const Random = Mock.Random
console.dir(Random.csentence(5, 30))

模拟resful处理的帖子

/*模拟删除数据的方式*/
var arr=[
    {name:'fei',age:20,id:1},
    {name:'liang',age:30,id:2},
    {name:'jun',age:40,id:3},
    {name:'ming',age:50,id:4}
]

Mock.mock('http://www.bai.com','delete',function(options){
    var id = parseInt(options.body.split("=")[1])//获取删除的id
    var index;
    for(var i in arr){
        if(arr[i].id===id){//在数组arr里找到这个id
            index=i
            break;
        }
    }
    arr.splice(index,1)//把这个id对应的对象从数组里删除
    return arr;//返回这个数组,也就是返回处理后的假数据
})

less的坑

如果less中 不能使用函数,那可能是style-css 和 less-loader顺序问题。

在less文件中无法使用css3的@keyfreames动画语法。这时可以在文件中定义一个类的keyfreames语句,然后在页面中使用improt style from 'xxx.less' 并在模版中使用

用这种龌龊的方法调用style

SEO问题

由于数据内容都是前端渲染出来的,所以不利于搜索引擎seo。这时需要server render来处理就好了。

你可能感兴趣的:(#,前端开发相关技术)