react看官方文档后的吸收

初始化一个react项目:

  1. 全局安装react脚手架工具: npm install -g create-react-app
  2. 使用脚手架工具初始化react项目: create-react-app 项目名
  3. 启动react项目: npm start

react 与 vue的异同?

react 核心知识点:

reactRouterDom

Router

ReactComponent

render

react

redux:中间件。可以改变数据流

常用中间件:

  • redux-logger:提供日志输出
  • redux-thunk:处理异步操作
  • redux-promise:处理异步操作,actionCreator的返回值是promise
    优缺点:
  • 一个组件需要的数据,必须由父组件传递过来。
  • 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,需要通过shouldComponentUpdate进行判断来阻止render。

react 函数组件与 class 组件:

函数组件:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

自定义组件:名称必须大写字母开头

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;//会渲染 Hello, Sara    {name: 'Sara'}作为props传入Welcome
ReactDOM.render(
  element,
  document.getElementById('root')
);
// 1. 我们调用 ReactDOM.render() 函数,并传入 <Welcome name="Sara" /> 作为参数。
// 2. React 调用 Welcome 组件,并将 {name: 'Sara'} 作为 props 传入。
// 3. Welcome 组件将 <h1>Hello, Sara</h1> 元素作为返回值。
// 4. React DOM 将 DOM 高效地更新为 <h1>Hello, Sara</h1>。

class 组件:

import React from 'react'
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

组件组合/嵌套:

//自定义一个函数组件
function Comment(props) {
  return (
    <div className="UserInfo">
      <img className="Avatar"
        src={props.author.avatarUrl}
        alt={props.author.name}
      />
      <div className="UserInfo-name">
        {props.author.name}
      </div>
    </div>
  );
}
//提取组件Avatar
function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}
function Comment(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.author} />
      <div className="UserInfo-name">
        {props.author.name}
      </div>
    </div>
  );
}
//提取组件UserInfo
function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.author} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}
function Comment(props) {
  return (
    <UserInfo user={props.author />
  );
}

react 的 props 不允许被更改

real DOM & Virtual DOM:

Virtual DOM/ 虚拟DOM:可以提高性能。

  • 虚拟DOM是一个节点树,它将元素作为对象。元素的属性和方法作为对象的属性和方法。
  • 虚拟dom相当于在 js 和 real DOM 中间加了一个缓存,利用 dom diff 算法避免了没必要的 dom 操作,从而提高性能。
    具体实现:
  1. 用js对象结构表示DOM树结构。用这棵树构建一个real DOM,插到文档中。
  2. 当状态变更时,重新构造一棵新的对象树 Virtual DOM 。新的和旧的进行比较,记录差异。
  3. 再把差异应用到步骤1创建的real DOM上,更新视图。

diff算法:?

把树结构按照层级分解。只比较同级元素。给列表结构每个元素添加唯一的 key ,方便比较。

react性能优化方案

React性能优化
(1)重写shouldComponentUpdate来避免不必要的dom操作。
(2)使用 production 版本的react.js。
(3)使用key来帮助React识别列表中所有子组件的最小变化。

flux:数据的单向流动

reacte脚手架工具: create-react-app

react元素渲染:

react没有热更新,数据修改无法自动更新。react元素就像电影的单帧,代表某个固定时刻的UI。
会专注于差异。只更新修改的部分。
react 更新UI的方式是通过 计时器和 ReactDOM.render()。 使得每秒更新UI

import ReactDOM from 'react-dom';
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
//计时器 + ReactDOM.render() 每秒更新UI
function tick() {
  const element = (
    <div>
      。。。
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}
setInterval(tick, 1000);

// 给UI添加一个时钟
function Clock(props) { 
  return (
    <div>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}
function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}
setInterval(tick, 1000);

以上的时钟只能在render的那一刻获取到那一刻的时间。怎样让这个时钟实现每秒更新呢?
向组件中添加 State ,是当前组件私有的属性,完全受控于当前组件。 this.setState

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

class Clock extends React.Component {//封装时钟的外观组件  
    constructor(props) {
      super(props);// 通过 super 将 props 传递到父类的构造函数中
      this.state = {date: new Date()};//构造函数是唯一可以给 this.state 赋值的地方
    }

    componentDidMount() {// 组件挂载 。在组件完全渲染后执行,类型mounted
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
    }
    componentWillUnmount() { // 组件要被删除时,卸载 unmount
        clearInterval(this.timerID);
    }

    tick() {
      this.setState({// state不要直接修改,使用setState()去修改 , state 改变会重新调用render()
        date: new Date()
      });
    }

    render() {
        return (// JSX 用法。JavaScript + xml
          <div>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
    }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

State & 生命周期: componentDidMount , componentWillUnmount

    1. state不要直接修改,使用setState()去修改
    1. 构造函数是唯一可以给 this.state 赋值的地方
this.state.m = 'aa';// wrong 
this.setState({ m: 'aa' });// right
    1. state 的更新可能是异步的,所以不要依赖 this.props 或者 this.state 的值来更新状态。让 setState()接收一个函数,state 作为第一个参数,props 作为第二参数
this.setState((state, props) => ({// 为了解决state存在异步更新情况,无法通过接收对象作为参数来处理 props 和 state 的问题,解决方法是接收一个函数作为参数:(state, props) => ({})
  counter: state.counter + props.increment
}));
    1. State 的更新会被合并:
import React from 'react'
import ReactDOM from 'react-dom';

class Com extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            a:[],
            b:{}
        }
    }

    componentDidMount() {
      fetchPosts().then(response => {
        this.setState({
          a: response.posts
        });
      });
      fetchComments().then(response => {
        this.setState({
          b: response.comments
        });
      });
    }
}

ReactDOM.render(
    <Com />,
    document.getElementById('root')
);
    1. state 数据是向下流动的 / 单向数据流 :因为 state 属于当前组件的私有属性,其他组件无法访问。但 state 可以作为 props 向下传递给子组件
<Comp mydate={this.state.date} />

function Comp(props) {
  return <h2>It is {props.mydate.toLocaleTimeString()}.</h2>;
}
    1. state状态提升。 将内容提升到共有的父组件中,通过props向下传递。通过 this.props.func(e.target.value); 去父组件真实处理业务逻辑

事件处理:

  1. 事件命名采用小驼峰,camlCase
  2. 使用JSX时需要传入一个函数参数作为事件处理函数
// react 
<button onClick={activateLasers}> Activate Lasers </button>
  1. 无法通过 return false 阻止默认行为,需要使用 preventDefault
function Form() {//class Form extends React.Component{}
  function mySubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }
  return (
    <form onSubmit={mySubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}
  1. 注意 this 的绑定,class 的方法默认不会绑定this。
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    // 为了在回调中使用 `this`,使用 bind()
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {// 使用箭头函数写法也可以使得 click 事件能访问到 class 的 this。   handleClick = () => {}
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
  render() {// onClick={ () => this.handleClick() }  直接在元素上通过箭头函数写法绑定函数也可以访问到 this
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);
  1. 给事件处理函数传递参数:
<button onClick={ (e) => this.deleteRow(id, e) }>Delete Row</button>
<button onClick={ this.deleteRow.bind(this, id) }>Delete Row</button>

条件渲染

与运算符:true && expression 总是会返回 expression, 而 false && expression 总是会返回 false , 0 && expression 会返回 0

组合 vs 继承:

// 包含关系
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}
function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } 
    />
  );
}
// 特例关系
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}
function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

组件可以接受任意 props,包括基本数据类型,React 元素以及函数。props 不能被修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值