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

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

引入react框架

1,直接在网页引入
<!--react主程序-->
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<!--与dom相关的操作库-->
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<!--转化es6与jsx语法支持-->
<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元素
    <h1>Hello, world!</h1>,
    //渲染目标元素
    document.getElementById('area')
)

元素

创建一个网页元素

//创建一个元素element
let element = <h1>Hello,element!</h1>
//element元素可以在render()直接中渲染
ReactDOM.render(
  element,
  document.getElementById('root')
);
//element元素可以在组件中调用
class Hello extends React.Component {
    render(){
        return (
            <ul>
              {listItems}
            </ul>
        );
    }
}    

组件

创建一个函数组件
function Hello(props) {
  return <h1>Hello, {props.name}</h1>;
}
创建一个类组件
//创建组件需要创建一个类,类名必须首字母大写,必须继承React.Component并实现render()方法
class Hello extends React.Component {
    render() {
        return <h1>Hello, world!</h1>
        //这里可以直接返回元素element
        //return element
    }
}
渲染组件
//将组件类名按html形式写在render方法中即可在页面中看到
ReactDOM.render(<Hello />, document.getElementById('root'))
组件相互调用
//组件A
class HelloA extends React.Component {
    render() {
        return <h1>this is A</h1>
    }
}
//组件B调用组件A
class HelloB extends React.Component {
    render() {
        return (
            <div>
                <h1>this is B</h1>
                //此处调用组件A
                <HelloA />
            </div>
        )
    }
}
元素调用组件
const element = <HellA />;
组件传值

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

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

子组件获取值

class HelloA extends React.Component {
    render() {
        //得到父组件传来的attr值
        return <h1>this is A {this.props.attr}</h1>
    }
}
值验证

引入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'>
              <p className='tes'>{this.props.name}</p>
          </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 (
            <h1>Hello, world!{this.state.date}</h1>
        );
    }
    //钩子函数  当虚拟dom挂在到网页dom上时立即执行
    componentDidMount() {
        this.timerID = setInterval(
           () => this.tick(),
           1000
       );
    }
    //钩子函数  当前dom即将从网页dom卸载时执行
    componentWillUnmount() {
        clearInterval(this.timerID);
    }
}

事件

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

<!--html:-->
<button onclick='someFun()'   />
<!--react+jsx:-->
<button onClick={someFun}   />

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

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

2,在调用时使用回调

<button onClick={(e) => this.clickFunc(e)}>

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

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

事件传值

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

    render() {
    //使用箭头函数传值。如果使用普通写法,函数会立即执行。
        <button key={index} className='button' onClick={() => this.handleClick(index)}>

列表

元素方式

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

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 (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          //在此处绑定组件的值,并且输入框的值发生改变时也会触发事件方法改变值
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

元素组合

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

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

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

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

状态提升

跨组件调用状态时,父组件通过属性传递到方式 将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>
        <TemperatureInput
          scale="c"
          //子组件到值来自父组件传递
          temperature={celsius}
          //子组件发生变化更新父组件到 setState控制方法
          onTemperatureChange={this.handleCelsiusChange} />

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

        <BoilingVerdict
          celsius={parseFloat(celsius)} />

      </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 我们想把 <input> ref 关联到构造器里创建的 `textInput` 上
    return (
      <div>
        <input
          type="text"
          ref={this.textInput}} />

        <input
          type="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 (
    <ThemeContext.Consumer>
      {theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
  );
}

// 中间组件
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class App extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

不被渲染到包裹标签Fragments

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

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

需要key的时候使用React.Fragment

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

将元素插入到现有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
            <BrowserRouter basename='/home'>
                //只能有一个子
                <div>
                    //组件容器。path设置匹配地址,component设置匹配组件。
                    <Route path='/about' component={About} />
                    <Route path='/contact' component={Contact} />
                    //链接按钮。相当于a标签
                    <Link to='about'>about</Link>
                    <Link to='contact'>contact</Link>
                </div>
            </BrowserRouter>
        )
    }
}

发起数据请求(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' 并在模版中使用<div style={style.keyfreamClassName }\/>用这种龌龊的方法调用style

SEO问题

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千年奇葩

从来没受过打赏,这玩意好吃吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值