react初认识

2020-03-29  本文已影响0人  janezhang
  1. JSX: javascript xml。是javascript的一种拓展语法。可以在js代码中编写更像xml写法的代码。它不能直接在浏览器中执行,需要经过转换器将jsx转换成js。本质上jsx是React.createElement()的语法糖。

2.转译工具:Babel来转换。早期提供浏览器当中的转译脚本,browser.js

3.react组件生命周期。

  1. react + redux数据流管理。
    redux动机:状态管理,预测与追踪状态的变化。
    三大特性:
    1.单一数据源:整个应用state都存储在一个js对象中。--Store
    2.state是只读的,只可以通过action修改。
    3.使用纯函数执行修改。相同输入,永远会得到相同的输出。

redux#组成:Action、Reducer、Store

Action:Store中数据的唯一来源,描述整个应用中的所有行为。
一个Action创建有3点
1.定义类型(type)
2. 定义内容
3. 定义Action Creator(Action生成函数)

Reducer: ( Action:负责dispatch对应的typeAction?---- reducer:根据对应的typeAction直接更改store?-----store )

  1. Action定义了要执行的操作,但没有规定如何更改state,而Reducer但职责定义整个应用的状态如何更改。它是一个纯函数。
  2. combineReducers(Object): 由于应用会比较复杂,reducer可以拆分多个单独的函数,单独负责管理state的一部分代码。最后用combineReducers(Object)方法连接
import { combineReducers } from 'redux'
import cart, * as fromCart from './cart'
import products, * as fromProducts from './products'

/**
 * 用于 Reducer 的拆分,定义各个子 Reducer 函数,然后用这个方法,
 * 将它们合成一个大的 Reducer
 */
export default combineReducers({
  cart,
  products
})

Store:4个api以及创建store。

import { createStore, applyMiddleware } from "redux";
//浏览器Redux工具,用于调试
import { composeWithDevTools } from 'redux-devtools-extension';  
// 创建store,整个应用中有且只有一个Store,用于存放整个应用中所有的state。
// store的创建,也相当于是reducer的创建作为createStore必传参数。
const store = createStore(reducer, composeWithDevTools(
  applyMiddleware(...middleware),   //applyMiddleware告诉createStore如何处理中间件
));

函数式组件:

1.通过mapStateToProps、mapDispatchToProps等state,action传入组件。

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { checkout } from '../../actions'
import { getTotal, getCartProducts } from '../../reducers'

const CartContainer = ({ products, total, checkout }) => {
  const hasProducts = products.length > 0;
  return (
    <div>
      <h3>您的购物车</h3><em>请选择以上商品</em>
      <div className="cart-container">
        <div>
          {
            products.map(product =>
              <div key={product.id}>{product.title} - {product.price}元{product.quantity ? ` x ${product.quantity} 本` : null}</div>
            )
          }
        </div>
        <p>总价是: {total}元</p>
      </div>
      <button className="submit-btn" onClick={() => checkout(products)}
        disabled={hasProducts ? '' : 'disabled'}>
        去结算
      </button>
    </div>
  )
}

CartContainer.propTypes = {
  products: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number.isRequired,
    title: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired,
    quantity: PropTypes.number.isRequired
  })).isRequired,
  total: PropTypes.string,
  checkout: PropTypes.func.isRequired
}

//mapStateToProps: 返回的对象的所有key都为当前组件的props
const mapStateToProps = (state) => ({
  products: getCartProducts(state),
  total: getTotal(state)
})

//conect个Provider相互配合将 Action和state传入 组件app。
// connect 主要作用是连接React组件与React Store
export default connect(
  mapStateToProps,    //state,
  { checkout }      //checkout这个应该是mapDispatchToProps,
)(CartContainer)


中间件:-----

react+redux +middleware(中间件)
redux是独立存在不属于react,可以搭配react使用。

react-redux2个重要的对象:Provider, connect.

Provider:包裹所有react组件,作为父组件,将store作为属性传给Provider。
connect:连接React组件与Redux Store,当前组件可以通过props获取应用中的state和Actions。(把state和action传给了组件用)
connect的4个参数:
mapStateToProps()、mapDispatchToProps()、mergeProps()和options。
mapDispatchToProps(): 这个可以通过redux提供的工具方法(bindActionCreators(action,dispatch))将action与dispatch绑定。
middleware:类似于在redux中间穿插一些记录日志、报错等等功能。

bindActionCreators工具函数的使用如下:将action与dispatch绑定
import { bindActionCreators } from "redux";
const mapDispatchToProps = dispatch => {
  return bindActionCreators(
    {
      signinUser,
      loginModalhide
    },
    dispatch
  );
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Login);

react路由

5. react的性能及优化

1. diff算法:

  1. Tree Diff
    对比虚拟DOM,把同一层级的节点遍历比较。只要不同就直接暴力删除。
  2. component Diff
    类型相同的组件则按照原来的策略继续比较tree。
    不同类型的组件,会将这个组件内部所有的子节点重新替换。
  3. element diff
    相同组件类型的,还会继续对组件内部元素进行对比,这就是element diff。进行插入、移动、删除这3种操作。

2. shouldComponentUpdate() 这里优化
是否需要更新组件用:

  1. react-addons-shallow-compare 插件。第三方插件:react-addons-pure-render-mixin。原理就是重写了shouldComponentUpdate这个生命周期,但它的内部做法是让新旧props进行浅比较(PureRender)只对对象进行了引用的比较(===比较),而没有作值的比较。
    浅比较源码:待补充。
  2. Immutable持久性数据结构库
    优点主要体现数据的不可变。
    Immutable和原生javascript对象相互转换。--- 待补充
    Immutable与React配合使用 -- 待补充。

调试工具:
redux-devtools-extension:https://github.com/zalmoxisus/redux-devtools-extension

/**
 * combineReducers用于 Reducer 的拆分,定义各个子 Reducer 函数,然后用这个方法,
 * 将它们合成一个大的 Reducer
 */
import { combineReducers } from 'redux'


import React from "react";
import { render } from "react-dom";
import { createStore, applyMiddleware } from "redux";
//浏览器Redux工具
import { composeWithDevTools } from 'redux-devtools-extension';  
// Redux顶层组件,用于包裹原有组件
import { Provider } from "react-redux";
//中间件,日志打印
import { createLogger } from "redux-logger";
// 中间件
import thunk from "redux-thunk";
// 应用的Reducer
import reducer from "./reducers";
//应用的Action
import { getAllProducts } from "./actions";
//应用的UI组件
import App from "./containers/App.jsx";
import "./index.css";

const middleware = [thunk];
if (process.env.NODE_ENV !== "production") {
  //开发环境就添加 日志打印
  middleware.push(createLogger());
}
// 创建store,整个应用中有且只有一个Store,用于存放整个应用中所有的state。
const store = createStore(reducer, composeWithDevTools(
  applyMiddleware(...middleware),
));

// 请求接口获取数据
store.dispatch(getAllProducts());

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

react组件:写法:

  1. connect突出作用:连接了store与组件。把state和action传给了组件用。
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { addToCart } from '../../actions'
import { getVisibleProducts } from '../../reducers/products'

const BooksContainer = ({ products, addToCart }) => (
  <div>
    <h2>网上书店</h2>
    <div className="products-container">
      {products.map(product =>
        <div key={product.id}>
          {product.title} - {product.price}元 库存数量: {product.inventory ? `${product.inventory}` : null}
          <button
            className="add-btn"
            onClick={() => addToCart(product.id)}
            disabled={product.inventory > 0 ? '' : 'disabled'}>
            {product.inventory > 0 ? '添加到购物车' : '售罄'}
          </button>
        </div>
      )}
    </div>
  </div>
)

BooksContainer.propTypes = {
  products: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number.isRequired,
    title: PropTypes.string.isRequired,
    price: PropTypes.number.isRequired,
    inventory: PropTypes.number.isRequired
  })).isRequired,
  addToCart: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
  products: getVisibleProducts(state.products)
})

export default connect(
  mapStateToProps,
  { addToCart }
)(BooksContainer)

import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
import { Provider } from "react-redux";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import reducer from "./reducers";

5.react生命周期


image.png

问题确认

上一篇 下一篇

猜你喜欢

热点阅读