React basics 3

React basics 3

12.react-ui

12.1 - the most popular open source React UI component library
a. Material UI (abroad)

1.Official website: http://www.material-ui.com/#/
2.github: https://github.com/callemall/material-ui

b. Ant Design / ANTD

1.PC Official website: https://ant.design/index-cn
2.Mobile official website: https://mobile.ant.design/index-cn
3.Github: https://github.com/ant-design/ant-design/
4.Github: https://github.com/ant-design/ant-design-mobile/

12.2 - Introduction to ant design mobile
1. Use create react app to create react application

	1.npm install create-react-app -g
	2.create-react-app antm-demo
	3.cd antm-demo
	4.npm start

2. Build the basic development environment of antd mobile
1 - Download

npm install antd-mobile --save

2-src/App.jsx

import React, {Component} from 'react'
// Introduce the components to be used separately
import Button from 'antd-mobile/lib/button'
import Toast from 'antd-mobile/lib/toast'
export default class App extends Component {
  handleClick = () => {
    Toast.info('Submitted successfully', 2)
  }
  render() {
    return (
      <div>
        <Button type="primary" onClick={this.handleClick}>Submit</Button>
      </div>
    )
  }
}

3- src/index.js

import React from 'react';
import ReactDOM from 'react-dom'
import App from "./App"
// Introduce overall css
import 'antd-mobile/dist/antd-mobile.css'
ReactDOM.render(<App />, document.getElementById('root'))

4- index.html

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
<script>
  if ('addEventListener' in document) {
    document.addEventListener('DOMContentLoaded', function() {
      FastClick.attach(document.body);
    }, false);
  }
  if(!window.Promise) {
    document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"'+'>'+'<'+'/'+'script>');
  }
</script>

3. Realize on-demand packaging (component js/css)
1. Download dependent packages

yarn add react-app-rewired --dev
yarn add babel-plugin-import --dev

2. Modify the default configuration:

//package.json
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test --env=jsdom"
}
//config-overrides.js
const {injectBabelPlugin} = require('react-app-rewired');
module.exports = function override(config, env) {
  config = injectBabelPlugin(['import', {libraryName: 'antd-mobile', style: 'css'}], config);
  return config;
};

3. Coding

import {Button, Toast} from 'antd-mobile'

13. Redux

13.1 understanding redux

Document link:http://www.redux.org.cn/
       :https://www.reduxjs.cn/introduction/getting-started
1.redux It is an independent and specialized tool for state management JS library(no react Plug in Library)
2.It can be used in react, angular, vue Etc, But basically react Use together
3.effect: Centralized management react The state shared by multiple components in the application

When do I need to use redux?

1   General principles: No need if you can, If you don't have to work hard, you can consider using it
2	The state of a component needs to be shared
3	A state needs to be available anywhere
4	A component needs to change the global state
5   One component needs to change the state of another component

redux workflow diagram

13.2 core API of Redux

1.createStore()
effect:
Create a store object containing the specified reducer
code:

import {createStore} from 'redux'
import counter from './reducers/counter'
const store = createStore(counter)

2.store object
effect:
The core management object of the redux library is internally maintained: state and reducer
Core method:
getState()
dispatch(action)
subscribe(listener)
code:

store.getState()
store.dispatch({type:'INCREMENT', number})
store.subscribe(render)	

3 . applyMiddleware()
effect:
Middleware based on redux in application (plug-in library)
code:

import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'  // redux asynchronous Middleware
const store = createStore(
  counter,
  applyMiddleware(thunk) // Asynchronous middleware on Application
)

4 . combineReducers()
effect:
Merge multiple reducer functions
code:

export default combineReducers({
  user,
  chatUser,
  chat
})

13.3 three core concepts of Redux

1 . action

1)Identifies the object to perform the behavior
2)Attributes containing 2 aspects
a.type: Identity attribute, The value is a string, only, Necessary attributes
b.xxx: Data properties, Arbitrary value type, optional attribute 
3)example:
		const action = {
			type: 'INCREMENT',
			data: 2
		}
4)Action Creator(establish Action Factory function of)
		const increment = (number) => ({type: 'INCREMENT', data: number})		

2 . reducer

1)According to the old state and action, Generate new state Pure function of
2)Example
		export default function counter(state = 0, action) {
		  switch (action.type) {
		    case 'INCREMENT':
		      return state + action.data
		    case 'DECREMENT':
		      return state - action.data
		    default:
		      return state
		  }
		}
3)be careful
a.Return to a new status
b.Do not modify the original state

3 . store

1)take state,action And reducer Linked objects
2)How do I get this object?
		import {createStore} from 'redux'
		import reducer from './reducers'
		const store = createStore(reducer)
3)Functions of this object?
		getState(): obtain state
		dispatch(action): distribute action, trigger reducer call, Generate new state
		subscribe(listener): Register listening, When a new state Time, Automatic call	

13.4 writing applications using redux

Download dependent packages

npm install --save redux

redux/action-types.js

/*
action Object's type constant name module
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

redux/actions.js

/*
action creator modular
 */
import {INCREMENT, DECREMENT} from './action-types'

export const increment = number => ({type: INCREMENT, number})
export const decrement = number => ({type: DECREMENT, number})

redux/reducers.js

/*
According to the old state and the specified action, the processing returns a new state
*/
import {INCREMENT, DECREMENT} from '../constants/ActionTypes'
import {INCREMENT, DECREMENT} from './action-types'

export function counter(state = 0, action) {
 console.log('counter', state, action)
 switch (action.type) {
   case INCREMENT:
     return state + action.number
   case DECREMENT:
     return state - action.number
   default:
     return state
 }
}

components/app.jsx

/*
Application component
 */
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import * as actions from '../redux/actions'

export default class App extends Component {
  static propTypes = {
    store: PropTypes.object.isRequired,
  }

  increment = () => {
    const number = this.refs.numSelect.value * 1
    this.props.store.dispatch(actions.increment(number))
  }

  decrement = () => {
    const number = this.refs.numSelect.value * 1
    this.props.store.dispatch(actions.decrement(number))
  }

  incrementIfOdd = () => {
    const number = this.refs.numSelect.value * 1
    let count = this.props.store.getState()
    if (count % 2 === 1) {
      this.props.store.dispatch(actions.increment(number))
    }
  }

  incrementAsync = () => {
    const number = this.refs.numSelect.value * 1
    setTimeout(() => {
      this.props.store.dispatch(actions.increment(number))
    }, 1000)
  }
  render() {
    return (
      <div>
        <p>
          click {this.props.store.getState()} times {' '}
        </p>
        <select ref="numSelect">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>{' '}
        <button onClick={this.increment}>+</button>
        {' '}
        <button onClick={this.decrement}>-</button>
        {' '}
        <button onClick={this.incrementIfOdd}>increment if odd</button>
        {' '}
        <button onClick={this.incrementAsync}>increment async</button>
      </div>
    )
  }
}

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import App from './components/app'
import {counter} from './redux/reducers'

// Create a store object according to the counter function
const store = createStore(counter)
// Defines the function that renders the root component label
const render = () => {
 ReactDOM.render(
   <App store={store}/>,
   document.getElementById('root')
 )
}
// Initialize rendering
render()
// Register (subscribe) to listen. Once the state changes, it will automatically re render
store.subscribe(render)

problem

1)redux And react The code coupling of the component is too high
2)The coding is not concise enough

13.5 react-redux

understand
1) A react plug-in library
2) Designed to simplify the use of redux in react applications
React Redux divides all components into two categories
1)UI components

a.Only responsible UI Without any business logic
b.adopt props receive data (General data and functions)
c.Do not use any Redux of API
d.Generally stored in components Under folder

2) Container assembly

a.Responsible for managing data and business logic, not UI Presentation of
b.use Redux of API
c.Generally stored in containers Under folder

Related API
1)Provider
Make state data available to all components

<Provider store={store}>
    <App />
  </Provider>

2)connect()
Container component used to wrap UI components

import { connect } from 'react-redux'
  connect(
    mapStateToprops,
    mapDispatchToProps
  )(Counter)

3)mapStateToprops()
Convert external data (i.e. state object) into tag properties of UI components

  const mapStateToprops = function (state) {
   return {
     value: state
   }
  }

4)mapDispatchToProps()
Convert the function that distributes the action into the tag attribute of the UI component
Concise syntax can be directly specified as actions objects or objects containing multiple action methods

Using react Redux
1) Download dependent packages

npm install --save react-redux

2)redux/action-types.js
unchanged
3)redux/actions.js
unchanged
4)redux/reducers.js
unchanged
5)components/counter.jsx

/*
UI Component: does not contain any redux API
 */
import React from 'react'
import PropTypes from 'prop-types'

export default class Counter extends React.Component {
  static propTypes = {
    count: PropTypes.number.isRequired,
    increment: PropTypes.func.isRequired,
    decrement: PropTypes.func.isRequired
  }
  increment = () => {
    const number = this.refs.numSelect.value * 1
    this.props.increment(number)
  }
  decrement = () => {
    const number = this.refs.numSelect.value * 1
    this.props.decrement(number)
  }
  incrementIfOdd = () => {
    const number = this.refs.numSelect.value * 1
    let count = this.props.count
    if (count % 2 === 1) {
      this.props.increment(number)
    }
  }
  incrementAsync = () => {
    const number = this.refs.numSelect.value * 1
    setTimeout(() => {
      this.props.increment(number)
    }, 1000)
  }
  render() {
    return (
      <div>
        <p>
          click {this.props.count} times {' '}
        </p>
        <select ref="numSelect">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>{' '}
        <button onClick={this.increment}>+</button>
        {' '}
        <button onClick={this.decrement}>-</button>
        {' '}
        <button onClick={this.incrementIfOdd}>increment if odd</button>
        {' '}
        <button onClick={this.incrementAsync}>increment async</button>
      </div>
    )
  }
}

6)containters/app.jsx

/*
Container component containing Counter component
 */
import React from 'react'
// Introduce connection function
import {connect} from 'react-redux'
// Introduce action function
import {increment, decrement} from '../redux/actions'
import Counter from '../components/counter'

// Expose packaging components connecting App components to the outside
export default connect(
  state => ({count: state}),
  {increment, decrement}
)(Counter)

7)index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import {Provider} from 'react-redux'
import App from './containers/app'
import {counter} from './redux/reducers'

// Create a store object according to the counter function
const store = createStore(counter)
// Defines the function that renders the root component label
ReactDOM.render(
  (
    <Provider store={store}>
      <App />
    </Provider>
  ),
  document.getElementById('root')

problem

1)redux Asynchronous processing is not allowed by default, 
2)In the application, we need to redux Executing asynchronous tasks in(ajax, timer)

13.6 redux asynchronous programming

Download redux plug-in (asynchronous Middleware)

npm install --save redux-thunk

index.js

import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
// Create a store object according to the counter function
const store = createStore(
 counter,
 applyMiddleware(thunk) // Asynchronous middleware on Application
)

redux/actions.js

// Asynchronous action creator (return a function)
export const incrementAsync = number => {
  return dispatch => {
    setTimeout(() => {
      dispatch(increment(number))
    }, 1000)
  }
}

components/counter.jsx

incrementAsync = () => {
 const number = this.refs.numSelect.value*1
 this.props.incrementAsync(number)
}

containers/app.jsx

import {increment, decrement, incrementAsync} from '../redux/actions'
// Expose packaging components connecting App components to the outside
export default connect(
  state => ({count: state}),
  {increment, decrement, incrementAsync}
)(Counter)

13.7 using redux debugging tool

Install the chrome browser plug-in
Download and decompress, and directly drag it into the extension program interface

Download tool dependency package

npm install --save-dev redux-devtools-extension

code

import { composeWithDevTools } from 'redux-devtools-extension'
const store = createStore(
  counter,
  composeWithDevTools(applyMiddleware(thunk)) 
)

13.8 relevant important knowledge: pure function and higher-order function

1. Pure function
1.1 a special kind of function: as long as it is the same input, it must get the same output
1.2 some of the following constraints must be observed
a. Parameters must not be overwritten
b. API of system I/O cannot be called
c. Can call date Now () or math Impure methods such as random ()
1.3 the reducer function must be a pure function
2. Higher order function
2.1 understanding: a special class of functions
a. Case 1: the parameter is a function
b. Case 2: return is a function
2.2 common high-order functions:
a. Timer setting function
b. map()/filter()/reduce()/find()/bind() of array
c. connect function in react Redux
2.3 function: it can realize more dynamic and scalable functions

Tags: ECMAScript React html5

Posted by ericburnard on Tue, 19 Apr 2022 05:33:18 +0930