React study notes one: basic knowledge

React development aids

chrome extension pack

1. React Devtools: View the tree structure of React components: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi

2. Redux Devtools: View Redux data flow: https://chrome.google. com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibtkpmmfibljd

3. React Perf: Found the performance problem of React component rendering: https://google.com/webstore/detail/react-perf/hacmcodfllhbnekmghgdlplbdnahrnhmm

If it is difficult to access the Google browser store, you can visit http://chrome-extension-downloader.com/, enter the last string connected above in the input box, and click the download extension package button.

 

1. Component life cycle:

The component life cycle is divided into three phases:

Creation process (mounting),
update process,
uninstall process

Understanding: the timing of execution of each stage; the execution order of hook functions in each stage

 

Creation process

Execution timing : when the page loads (when the component is created)

The execution order of hook functions is also in accordance with the writing order
constructor: trigger timing-execute first when creating the component; used to initialize the state and bind this
getInitialState
getDefaultProps
componentWillMount for the event handler . It is not used here, even if the data is modified here, but also when rendering It will not be updated, and the initial data is best in the constructor;
render: trigger timing---triggered every component rendering; used to render UI (setState() cannot be called because render will be triggered after state changes)
componentDidMount: trigger timing- --After the component is mounted (complete DOM rendering); used to send network requests and DOM operations

1) Constructor is not necessarily defined in the class. It is
only defined when state is needed. When props is used
in the this environment for initializing state binding member functions
, the constructor is not defined and super(props) is initialized, which can inherit from the parent. props? ? ? ?

1) getInitialState\\getDefaultProps is called in createClass

2) componentWillMount is executed immediately before render, but componentDidMount executes the corresponding componentDidMount in the order of render after the components of the entire page are rendered.

3) The difference between componentWillMount and componentDidMount
componentWillMount can be called in the browser and the server; componentDidMountz can only be called in the browser, because loading is to create a component and put it on the DOM, and the server does not generate a DOM tree, so it can only be viewed Call on the device

4)
Render is a method that must be implemented by React.component. Render does not perform the century rendering action and returns the JSX description structure. The
render function of the React operation rendering process returns null false, then this component does not need to render any elements. The
render function should be a pure function


Timing of the update process : setState() calls forceUpdate() and the component receives new props

The order of execution is as follows:

componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render: trigger timing-----every component rendering will be triggered; rendering UI
componentDidUpdate: trigger timing-----after component update (complete DOM rendering); used to send network requests, DOM operations, if necessary setState must be placed in an if, otherwise it will cause recursive updates

Note: Not all updates will perform the above method
1) componentWillReceiveProps (nextProps)
trigger timing: as long as the parent component’s render call, regardless of whether the props passed by the parent component to the child component change, it will trigger the component’s componentWillReceiveProps
update triggered by setState. Will not deploy the method

 

Uninstall

Execution timing: the component disappears from the page

Hook function: componentWillUnmount;

Trigger timing: component uninstall;

Role: perform cleanup work (clear timers, etc.)

 


2. Data: props (passed from the outside to the component, modification is not allowed) state (internal data, dynamic modification state)

1、props

1) The type of props can be set and checked through propTypes
className.propTypes = {   caption: PropTypes.string.isRequired,    initValue: PropTypes.number } This type check is only an error in the console and will not affect the interaction, so it should only be in development Environmental use, production should be removed, babel-react-optimize can be used to ensure that it is only used in production



2) className.defaultProps can set default values ​​for props

When the component is called, if no attribute is defined, the default value will be used

3. State
can set default values ​​for props through className.defaultProps, and there is no need to write default values ​​when initializing state with props

 

Three ways of data communication in react

The parent component transfers data to the child component, the child component transfers data to the parent component, the adjacent component transfers data, and the multi-level nested component transfers data

1), the parent to the child component data

1) Pass data to the child component through props, and define props on the child component reference, such as name, the value is the name of the variable defined on the state in the parent component

2) Sub-function components get data props.name through props, and class components get data through this.props.name

 

2), the child component passes data to the parent component

1) Define the method handleData in the parent component

2) Add props on the sub-component reference, such as onClick, the value is handleData

3) Define the trigger event in the child component, call the function component to call props.handleData(), and the class component to call this.props.handleData()

 

3), adjacent components transfer data

1) By defining a shared variable a in the state of the parent component

2) The method changeA() is defined in the parent component to change the value of the shared variable

3) Use variable a and method changeA as props to subcomponents

So as to achieve the purpose of data transmission between adjacent components

 

4), deeply nested components to transfer data

For example, A=》B=》C=》D, now it is necessary to transfer data from A to D. In addition to props, it can also be passed in context.

1) Component Provider improves data, component Consumer consumes data

const { Provider, Consumer } = React.createContext()

2) Use the Provider component as the parent node, and set the value attribute to indicate the data to be passed

<Provider value="pinker">
....
</Provider>

3) Invoke the Consumer component to receive data in the sub-component that wants to receive data

<Consumer>
  {data => <span>接收到的数据为:{data}</span>}
</Consumer>

 

4. Component reuse

Reuse: Reuse state, method of operating state (component state logic)

There are two ways to reuse components:

1) The component is the input parameter, and the return is the component----high-level component HOC

2) Render props mode

render props mode

When the component is created, the render method inside the component uses this.props.render, that is

render() {
  return this.props.render(this.state)
}

When using a component, add a props whose value is a function, obtain the internal data of the component through the function parameter, and write the ui according to the actual component. 

<Mouse render={(mouse) => (
   <p>数据为:{mouse.x}、{mouse.y}</p>
)}>

Note that you can use props.children instead of the props.render property, that is, you can no longer define the property render in the tag when using the component

When the component is created, change the render function to the following form

render() {
  return this.props.children(this.state)
}

When the component is used:

<Mouse>
  {
    (mouse => {
       return (
         <P>数据为:{mouse.x}、{mouse.y}</P>
       )
    })
  }
</Mouse>

High-end components

HOC is a function, the parameter is the component, and the new component is returned

displayName property, pass props to avoid loss of props

Add new props to the original component

class Mouse extends React.component{
  render () {
       return <WrappedComponent {...this.state} />
  }
}

Steps for usage:

1) Create a function starting with with

2) Specify function parameters, the parameters start with a capital letter

3) Create class components inside the function to provide reused state logic code

4) In the component, render the parameter component, and at the same time pass the state to the parameter component through props

5) Call high-level components, pass in the components to be enhanced, get the enhanced components through the return value, and render them to the page

// 创建高阶组件
function withMouse(WrappedComponent) {
  // 该组件提供服用的逻辑
  class Mouse extends ReadableByteStreamController.component {
    // 鼠标状态
    state = {
      x: 0,
      y: 0
    }
    handleMouseMove = (e) => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }
    // 控制鼠标状态逻辑
    componentDidMount() {
      window.addEventListener('mousemove', this.handleMouseMove)
    }
    // 解绑事件
    componentWillUnmount() {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }
    // 渲染
    render() {
      return (
        // 通过props,将数据传递给传入组件
        <WrappedComponent {...this.state}></WrappedComponent>
      )
    }
  }
  return Mouse
}

// 测试高阶组件
const Position = (props) => (
  <p>鼠标当前位置:(x: {props.x}, y: {props.y})</p>
)

const Cat = (props) => (
  <img style={
   
   {
    position: 'absolute',
    top: props.y - 64,
    left: props.x - 64
  }} alt="cat" />
)

// 获取增强后的组件
const MousePosition = withMouse(Position)
// 创建高阶组件
function withMouse(WrappedComponent) {
  // 该组件提供服用的逻辑
  class Mouse extends ReadableByteStreamController.component {
    // 鼠标状态
    state = {
      x: 0,
      y: 0
    }
    handleMouseMove = (e) => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }
    // 控制鼠标状态逻辑
    componentDidMount() {
      window.addEventListener('mousemove', this.handleMouseMove)
    }
    // 解绑事件
    componentWillUnmount() {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }
    // 渲染
    render() {
      return (
        // 通过props,将数据传递给传入组件
        <WrappedComponent {...this.state}></WrappedComponent>
      )
    }
  }
  return Mouse
}

// 测试高阶组件
const Position = (props) => (
  <p>鼠标当前位置:(x: {props.x}, y: {props.y})</p>
)

const Cat = (props) => (
  <img style={
   
   {
    position: 'absolute',
    top: props.y - 64,
    left: props.x - 64
  }} alt="cat" />
)

// 获取增强后的组件
const MousePosition = withMouse(Position)
const CatPosition = withMouse(Cat)

// 在页面中渲染MousePosition\CatPosition组件

Question: The names rendered by the above two components are both <Mouse>

Reason: By default, React uses the component name as the displayName

Solution: Set displayname for high-level components to facilitate debugging and distinguish different components

Setting method:

// 设置displatname
Mouse.displayName = `With${getDisplayName(WrappedComponent)}`

function getDisplayName(WrappedComponent) {
  // 有设置属性displayName,WrappedComponent.name表示创建的新高阶组件名称
  return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

 

// 创建高阶组件
function withMouse(WrappedComponent) {
  // 该组件提供服用的逻辑
  class Mouse extends ReadableByteStreamController.component {
    // 鼠标状态
    state = {
      x: 0,
      y: 0
    }
    handleMouseMove = (e) => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }
    // 控制鼠标状态逻辑
    componentDidMount() {
      window.addEventListener('mousemove', this.handleMouseMove)
    }
    // 解绑事件
    componentWillUnmount() {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }
    // 渲染
    render() {
      return (
        // 通过props,将数据传递给传入组件
        <WrappedComponent {...this.state}></WrappedComponent>
      )
    }
  }
  // 设置displatname
  Mouse.displayName = `With${getDisplayName(WrappedComponent)}`
  return Mouse
}
function getDisplayName(WrappedComponent) {
  // 有设置属性displayName,WrappedComponent.name表示创建的新高阶组件名称
  return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

// 测试高阶组件
const Position = (props) => (
  <p>鼠标当前位置:(x: {props.x}, y: {props.y})</p>
)

const Cat = (props) => (
  <img style={
   
   {
    position: 'absolute',
    top: props.y - 64,
    left: props.x - 64
  }} alt="cat" />
)

// 获取增强后的组件
const MousePosition = withMouse(Position)
const CatPosition = withMouse(Cat)

// 在页面中渲染MousePosition组件

Problem: pass props to avoid loss of props

<MousePosition a={1} />

// 在Mouse中的render,state和props一起传递
<WrappedComponent {...this.state} {...this.props}></WrappedComponent>

 

 

Guess you like

Origin blog.csdn.net/tangxiujiang/article/details/113814680