学习React必看笔记

React的核心思想就是:封装组件

1、React语法格式

// App.js是在定义一个React组件(父组件)
import React, { Component, Fragment } from 'react';
import TodoItem from './TodoItem';
import './index.css';

// TodoList 继承 react的组件,就变成了TodoList组件
class TodoList extends Component {
  // ES6的函数的构造函数,组件创建的一瞬间,constructor函数会自动被执行
  constructor(props) {
    // 初始化
    super(props);
    // 数据存放的位置
    this.state = {
      inputValue: '',
      list: [
        '列表是子组件,文本框和添加按钮是父组件',
        'learn english',
        'learn english',
        'learn english'
      ]
    }
    this.inputChange = this.inputChange.bind(this);
    // this.handleBtnClick = this.handleBtnClick.bind(this);
    this.deleteItem = this.deleteItem.bind(this);
  }
  inputChange (e) { // input的change事件
    this.setState({
      inputValue: e.target.value
    })
  }
  // 该组件的事件
  handleBtnClick () { // 添加的点击事件
    if (this.state.inputValue !== '') {
      this.setState({
        // ...是展开运算符,相当于
        // ['learn react', 'learn english', 'hellow world']
        list: [...this.state.list, this.state.inputValue],
        inputValue: ''
      })
    }
  }
  handleItemClick (index) { // li标签的点击事件
    const list = [...this.state.list]
    list.splice(index, 1)
    this.setState({
      list: list
    })
  }
  deleteItem (index, num) { // 获取子组件传递过来的值
    console.log(index, num);
    const list = [...this.state.list]
    list.splice(index, 1)
    this.setState({
      list: list
    })
  }
  bianliItem () {
    return (
      this.state.list.map((item, index) => {
        return (
          <TodoItem
            delete={this.deleteItem}
            key={index}
            content={item}
            index={index}/>
        )
      })
    )
  }
  render() {
    return (
      <Fragment>
        <div>
          <input value={this.state.inputValue} onChange={this.inputChange} />
          <button className='add-btn' style={{color: 'red'}} onClick={() => this.handleBtnClick()}>add</button>
        </div>
        {/* 遍历组件的两种方法: */}
        {/* 1、使用方法遍历 */}
        {/* <ul>{this.bianliItem()}</ul> */}
        {/* 2、直接遍历在jsx代码中 */}
        <ul>
          {
            this.state.list.map((item, index) => {
              return (
                <TodoItem
                  delete={this.deleteItem}
                  key={index}
                  content={item}
                  index={index}/>
              )
            })
          }
        </ul>
      </Fragment>
    ) 
  }
}

export default TodoList;

2、jsx语法

jsx其实是语法糖
const title = <h1 className="title">Hello, world!</h1>;可以转化成:
const title = React.createElement( 'h1', { className: 'title' }, 'Hello, world!' );

  • React 的jsx语法创建的UI元素其实就是虚拟DOM,当执行了render函数之后,虚拟DOM变成了真正的DOM元素
  • React 虚拟DOM的属性:

class: className
事件:onXXX eg: onClick、onChange
style: 就是style
其他的就是写的什么就是什么

3、 React.js diff算法

diff算法的定义:
每次更新DOM都是只更新需要更新的部分,极大地减少了DOM操作
diff算法的原则:
1、 对比当前真实的DOM和虚拟DOM,在对比过程中直接更新真实DOM
2、只对比同一层级的变化

4、 异步的setSate

  • React组件每次调用setState后会立即调用renderComponent重新渲染组件,但现实情况是,我们可能会在极短时间内多次调用setState,所以出于性能考虑,React可能会把多个setState()调用合成一个调用,所以setSate()方法可能无法实现一个定时器,要解决这个问题,可以让setState()接受一个函数而不是一个对象。这个函数用上一个state做为第一个参数,将此次更新被应用时的props做为第二个参数:
// Correct,次数的函数可以使箭头函数也可以是普通函数,实质是一样的
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

5、 组件

React定义组件的方式可以分为两种:函数和类,函数定义可以看做是类定义的一种简单形式。

React中改变state里面的值用setState来改变,在改变数据的同时,也会更DOM,使数据双向展示在页面上
setState的操作是异步的,要想拿到实时的数据,可以在回调函数中做一些操作

  • 定义组件
    由于React的核心就是封装组件,所以React的每一个页面展示都是组件,不论是父组件还是子组件,声明组件的方式是一样的,组件对象中有钩子函数,自己定义的方法,和render方法
class TodoItem extends Component {}
export default TodoItem;

6、 子组件和父组件之间的通讯

1、调用子组件:
创建:
class TodoItem extends Component {}
export default TodoItem;
引入(用到TodoItem组件中):
import TodoItem from './TodoItem';
使用:
<TodoItem />
2、父组件向子组件传值:

父组件:
<TodoItem content={item}/>
content就是父组件传递给子组件的值

子组件:

this.props.content 就是接受的父组件的值,但是此组件中要有constructor方法
  render() {
    return (
      <div onClick={() => this.handlClick()}>
        <span>{this.props.content}</span> 
      </div>
    )
  }

3、子组件向父组件传值
子组件:
子组件触发点击事件,执行handlClick方法,而该方法中的操作是传递给父组件一个方法-delete,值为子组件传递给父组件的值

  render() {
    return (
      <div onClick={() => this.handlClick()}>
        <span>{this.props.content}</span> 
      </div>
    )
  }
  handlClick () {
    this.props.delete(this.props.index, '22222222')
  }

父组件:
delete就是接收子组件传递过来的方法,在父组件中新定义一个方法来接收参数:

jsx:
<TodoItem
 delete={this.deleteItem}
 key={index}
 content={item}
 index={index}/>
 函数:
   deleteItem (index, num) { // 获取子组件传递过来的值
    console.log(index, num);
    const list = [...this.state.list]
    list.splice(index, 1)
    this.setState({
      list: list
    })
  }

7、 组件的生命周期函数

声明周期函数可以很好的帮助我们处理组件中的数据,和一些操作

在这里插入图片描述
在这里插入图片描述

componentWillMount ------ 组件将要挂载时触发的函数
componentDidMount ------- 组件挂载完成时触发的函数
shouldComponentUpdate ------- 是否要更新数据时触发的函数
componentWillUpdate ------- 将要更新数据时触发的函数
componentDidUpdate ------- 数据更新完成时触发的函数
componentWillUnmount -------组件将要销毁时触发的函数
componentWillReceiveProps ------- 父组件中改变了props传值时触发的函数

8、UI框架(Ant Design简称antd)

  • 下载:npm install antd --save
  • 按需引入:

    import { Form, Icon, Input, Button } from 'antd';
    import 'antd/dist/antd.css';

  • antd表单的使用
import React, { Component,Fragment } from 'react';
import { Form, Icon, Input, Button } from 'antd';
import 'antd/dist/antd.css';
import './index.less';
class TodoList extends Component {
  submitBtn = e => { // 提交按钮的点击事件
    // 获取antd表单文本框的值
    let username = this.props.form.getFieldValue('username');
    console.log(username);
    // 改变antd表单文本框的值
    this.props.form.setFieldsValue({
      username: '我是改变后的值'
    })
  }
  render () {
    // getFieldDecorator用于和表单进行双向绑定
    const {getFieldDecorator} = this.props.form
    return (
      <Fragment>
        <Form className="form_box">
          <Form.Item>
            {getFieldDecorator('username', {
              rules: [{ required: true, message: 'Please input your username!' }],
            })(
              <Input
                prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
                placeholder="Username"
              />,
            )}
          </Form.Item>
          <Form.Item>
            <Button type="primary" className="submi_btn" onClick={this.submitBtn}>
              确定
            </Button>
          </Form.Item>
        </Form>
      </Fragment>
    )
  }
}

// 使用getFieldDecorator的时候,导出这样导出才能使用getFieldDecorator
export default Form.create()(TodoList);

9、 React路由

1、安装:
cnpm i -S react-router-dom
2、 初始化路由
新建router.js
在router.js文件中写路由地址

import React from 'react'
import {
  BrowserRouter, Route, Switch
} from 'react-router-dom'
import TodoList from '@/TodoList'

export default () => (
  <BrowserRouter>
    <Switch>
      <Route path='/' component={TodoList}></Route>
    </Switch>
  </BrowserRouter>
)

3、将router.js引入到index.js入口文件中

import React from 'react';
import ReactDOM from 'react-dom';
// import TodoList from '@/TodoList';
import RouterDOm from '@/router.js'

// 原本render渲染的是TodoList,当引入路由之后,渲染路由,即可实现什么路由下面显示什么组件
ReactDOM.render(<RouterDOm />, document.getElementById('root'));

4、在组件中需要跳转路由的时候引入link跳转即可

// 引入:
import { Link } from 'react-router-dom';

// 在render中使用:
<div>
    <Linkto='/Tab'>跳转到tab栏切换页面</Link>
</div>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值