[Notes] react learning and recording

Posted by Old Novus on Mon, 10 Jan 2022 18:41:54 +0100

Basic Essentials

start

npm i -g create-react-app
create-react-app todolist
npm run start

src-> App.js,index.js

import {Component} from 'react';
//Equivalent to
import React from 'react';
const Component = React.Component

So app.js can be written like this

import React,{Component} from 'react';

class App extends Component {
  render() {
    return (
      <div>
       hello world
      </div>
    );
  }
}

export default App;

adopt
import React from 'react';
Compile jsx syntax in react

index entry file

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';


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

Responsive Design Ideas and Event Binding

1.js expression requires curly bracket wrapping
value={this.state.inputValue}
2. Event binding requires bind(this) to change the function scope
onChange={this.hanleInputChange.bind(this)}
3. Changing the data content does not directly change the form in which setState is required to pass in objects
this.setState({
inputValue:e.target.value
})

Supplemental Delete Function

import React,{ Component,Fragment } from 'react';
class ToDoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
            list: []
        }
    }
    render() {
        return (
            <Fragment>
                <div>
                    <input 
                    value={this.state.inputValue}
                    onChange={this.hanleInputChange.bind(this)}
                    />
                    <button onClick={this.hanleBtnClick.bind(this)}>Submit</button>  
                </div>
                <ul>
                    {
                        this.state.list.map((item, index) => {
                            return ( 
                            <li 
                            key = {index}
                            onClick={this.handleItemDelete.bind(this, index)}>
                                
                           {index}---{item}
                            </li>
                            )
                        })
                    }
                </ul>
            </Fragment>
        )
    }
    hanleInputChange(e) {
        this.setState({
            inputValue:e.target.value
        })
    }
    hanleBtnClick() {
        this.setState({
            list:[...this.state.list, this.state.inputValue],
            inputValue: ''
        })
    }
    handleItemDelete(index) {
        console.log(index);
        //immutable concept
        //state does not allow us to make any changes so make a copy and modify the copy
        // list.state.list.splice(index, 1) is not a valid way to write 
        const list = [...this.state.list] //Is a copy
        list.splice(index, 1)
        //react changing data requires calling setState
        this.setState({
            list: list 
        })
    }
}
export default ToDoList;

Counter Increase/Decrease and Cycle Cases

import React,{ Component,Fragment } from 'react';
import  './style.css'
class ToDoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
          movies:[1,2,3,4],
          count:0
        }
    }
    render() {
        const liArray = []
        for (let movies of this.state.movies){
            liArray.push(<li>{movies}</li>)
        }
        return (
            <div>
                <ul>
                    {liArray}
                </ul>
                <div>
                    {this.state.count}
                    <button onClick={this.a.bind(this)}>+</button>
                    <button onClick={this.b.bind(this)}>-</button>
                </div>
            </div>
        )
           
        
    }
    a() {
        this.setState({
            count:this.state.count+1
        })
    }
    b() {
        this.setState({
            count:this.state.count-1
        })
    }

}
export default ToDoList;

Writing Attention

1. Comments
{
/*How comments are written in jsx*/
}

2.css uses className or it is easy to classify
otherwise

Solutions

3.htmlFor
For in react disambiguates the for loop, so for in label uses htmlFor

4. Data type cannot be displayed directly
Design Reasons
_flag?' a': null generates many nulls or empty strings that are not as good as rendering
Solution+''
{this.state.test+ ' '}

class ToDoList extends Component {
constructor(props) {
    super(props);
    this.state = {
      age:18,
      name:'a',
      names:['a','b','c'],
      test1:null,
      test2:undefined,
      test3:true
    }
}
render() {
    
    return (
        <div>
      <div>{this.setState.name}</div>
            <div>{this.setState.age}</div>
            <div>{this.setState.names}</div>
            <div>{this.setState.test1}</div>
            <div>{this.setState.test2}</div>
            <div>{this.setState.test3}</div>
        </div>
    )
       
    
}

}`

Object-oriented

 		class Person {
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }
            running() {
                console.log('runnning');
            }
        }
        class Student extends Person {
            constructor(name, age, sno) {
                super(name, age);
                this.sno = sno;
            }
        }
        const stu = new Student('a', 18, 1)
        console.log(stu.name, stu.age, stu.sno);
        stu.running();

Splitting values between components

Parent component passes data to child component

Passing through attributes on tags can transfer both data and methods

 				{
                        this.state.list.map((item, index) => {
                            return ( 
                            <div>
                            <TodoItem content={item}/>

                            { /*<li 
                            key = {index}
                            onClick={this.handleItemDelete.bind(this, index)}
                            dangerouslySetInnerHTML={{__html: item}}>       
                            {item}
                            </li>  */}
                        </div>
                            )
                        })
                    }
import React, {Component} from 'react'
class TodoItem extends Component {
    render() {
        return <div>{this.props.content}</div>
    }
}
export default TodoItem

Subcomponents pass data to parent components

Subcomponents pass through this.props reception
The parent component's method is bound once

Code

import React,{ Component,Fragment } from 'react';
import './style.css'
import './TodoItem'
import TodoItem from './TodoItem';
class ToDoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
            list: []
        }
    }
    render() {
        return (
            <Fragment>
                <div>
                    <label htmlFor='insertArea' >Input Content</label>
                    <input 
                    id='insertArea'
                    className='input'
                    value={this.state.inputValue}
                    onChange={this.hanleInputChange.bind(this)}
                    />
                    <button onClick={this.hanleBtnClick.bind(this)}>Submit</button>  
                </div>
                <ul> 
                    {
                        this.state.list.map((item, index) => {
                            return ( 
                            <div>
                            <TodoItem 
                            content={item}
                            index={index}
                            deleteItem={this.handleItemDelete.bind(this)}
                             />

                            { /*
                            Parent components pass their own methods to child components through the deleteItem method 
                            <li 
                            key = {index}
                            onClick={this.handleItemDelete.bind(this, index)}
                            dangerouslySetInnerHTML={{__html: item}}>       
                            {item}
                            </li>  */}
                          </div>
                            )
                        })
                    }
                </ul>
            </Fragment>
        )
    }
    hanleInputChange(e) {
        this.setState({
            inputValue:e.target.value
        })
    }
    hanleBtnClick() {
        this.setState({
            list:[...this.state.list, this.state.inputValue],
            inputValue: ''
        })
    }
    handleItemDelete(index) {
        console.log(index);
        //immutable concept
        //state does not allow us to make any changes so make a copy and modify the copy
        // list.state.list.splice(index, 1) is not a valid way to write 
        const list = [...this.state.list] //Is a copy
        list.splice(index, 1)
        //react changing data requires calling setState
        this.setState({
            list: list 
        })
    }
}
export default ToDoList;
import React, {Component} from 'react'
class TodoItem extends Component {
    constructor(props) {
        super(props)
        this.handleclick=this.handleclick.bind(this)
    }
    render() {
        return (
        <div 
        onClick={this.handleclick}>
            {this.props.content}
        </div>)
    }
    handleclick() {
        this.props.deleteItem(this.props.index)
    {/*Calling the deleteitem method passed by the parent component will pass the index back as a parameter */}
    }
}
export default TodoItem

Code optimization

import React,{ Component,Fragment } from 'react';
import './style.css'
import TodoItem from './TodoItem';
class ToDoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
            list: []
        }
        this.hanleInputChange = this.hanleInputChange.bind(this)
        this.hanleBtnClick = this.hanleBtnClick.bind(this)
        this.handleItemDelete = this.handleItemDelete.bind(this)
    }
    render() {
        return (
            <Fragment>
                <div>
                    <label htmlFor='insertArea' >Input Content</label>
                    <input 
                    id='insertArea'
                    className='input'
                    value={this.state.inputValue}
                    onChange={this.hanleInputChange.bind(this)}
                    />
                    <button onClick={this.hanleBtnClick.bind(this)}>Submit</button>  
                </div>
                <ul> 
                    {this.getTodoItem()}
                </ul>
            </Fragment>
        )
    }
    getTodoItem() {
       return  this.state.list.map((item, index) => {
            return ( 
            <div>
                {
                //If there is a key value at the outermost level of the loop
                }
            <TodoItem 
            content={item}
            index={index}
            deleteItem={this.handleItemDelete.bind(this)}
             />
          </div>
            )
        })
    }
    hanleInputChange(e) {
        const value = e.target.value
        this.setState(() => ({
            inputValue:value
        }))
        // this.setState({
        //     inputValue:e.target.value
        // })
    }
    hanleBtnClick() {
        // prevState is the state of a state on the code
        this.setState((prevState) => ({
            list:[...prevState.list, prevState.inputValue],
            inputValue: ''
        }))
        // this.setState({
        //     list:[...this.state.list, this.state.inputValue],
        //     inputValue: ''
        // })
    }
    handleItemDelete(index) {
        
        this.setState((prevState) => {
            const list = [...prevState.list] 
            list.splice(index, 1)
            return {list}
        })
        // const list = [...this.state.list] 
        // list.splice(index, 1)
        // this.setState({
        //     list: list 
        // })
    }
}
export default ToDoList;
import React, {Component} from 'react'
class TodoItem extends Component {
    constructor(props) {
        super(props)
        this.handleclick=this.handleclick.bind(this)
    }
    render() {
        const { content } =  this.props 
        return (
        <div 
        onClick={this.handleclick}>
            {content}
        </div>
        )
    }
    handleclick() {
        const { deleteItem, index } = this.props
        deleteItem(index)
    {/*Calling the deleteitem method passed by the parent component will pass the index back as a parameter */}
    }
}
export default TodoItem

Thoughts Derived from Reaction

1. Command programming: direct operation dom jq, native
Famous Development: Data-oriented programming, saving a lot of code for dom operations
2. Writing react can coexist with other frameworks

react takes care of only the part with id='root'and does not affect the outside
3. Componentization
Parent-Child Component Communication Parent-Child Component Pass Value to Child Component Calls Method Passed by Parent Component
4. One-way data flow
A parent component can pass values to a child component, which cannot modify the parent component's values directly
Chestnut: If a parent component has five children, it is more complex if the data is mislocated
5. View Layer Framework
Solve data and page rendering issues
Large project processing data transfer values is complex

6. Functional programming

1. Easy maintenance, functions can be split when they are large
2. Test-oriented convenience

react Advanced Content

Install react development debugging tool

PropTypes and DefaultProps

https://reactjs.org/docs/typechecking-with-proptypes.html

Relationship between props, state and render function

The render function is reexecuted when the component's state or props change

When the render function of the parent component is run, the render of its child components will be rerun

Virtual dom in react (understanding is not enough to complement later)

1.state data
2.jsx Template
3. Data + templates combine to generate true dom for display
4.state changed
5. Data + templates combine to generate true dom, replacing original DOM
Defects:
The first time a complete dom fragment was generated
Two complete dom fragments were generated a second time
The second DOM replaces the first dom, which consumes performance
1.state data
2.jsx Template
3. Data + templates combine to generate true dom for display
4.state changed
5. Data + templates combine to produce true dom, not directly replacing the original DOM
6. Compare the new dom (DocumentFragment) with the original dom to find differences
7. Find that the input box has changed
8. Replace input elements from old DOMS with only the new ones
Defects:
Performance improvements are not noticeable
1.state data
2.jsx Template
3. Data + templates combine to generate true dom for display

hello world
4. Generate virtual DOM (virtual DOM is a js object that describes the real dom) ['div',{id:'abc'},{span,{},'hello world'}] 5.state changed 6. Generate a new virtual DOM (a virtual DOM is a js object that describes the real dom) ['div',{id:'abc'},{span,{},'bye'}] 7. Compare the difference between the original virtual Dom and the new virtual DOM 8. Directly manipulate the DOM to change the contents of the space

ref

ref is used to help us get DOM directly in react
ref={(input) => {this.input=input}}

life cycle

At some point the component automatically calls the executed function
https://juejin.cn/post/6844903842430074893
Improving component performance through lifecycle

shouldComponentUpdate(nextProps,nextState){
        if (nextProps.content !== this.props.content) {
            return true
        } else {
        return false
        }
    }

Initiate ajax requests with lifecycle
First npm install axios

  componentDidMount() {
        axios.get('/api/todolist')
        .then(() =>{
            alert('success')
        })
        .catch(() => {
            alert('error')
        })
    }

Local data mock using Charles

http://localhost.charlesproxy.com:3000/
Charles Map Local Invalidation Solution for axios Request Report 404 (Complete Step)
https://blog.csdn.net/weixin_43735348/article/details/100824002

redux


Store your data in a public store. Keep as little data as possible in components. Change the data in stores when the green component needs to change the data. Grey data reads the data in stores once it changes.
Redux = Reducer + Flux

Redux is the best data-tier framework in the current React ecology. Redux is a JavaScript application tool for managing data and UI states.

The process is represented abstractly by the state of the borrowed book

Using antd to implement todoList


todolist.js

import React, { Component } from 'react'
import 'antd/dist/antd.css'
import { List, Input, Button } from 'antd'
import store from './store'


class TodoList extends Component {
	constructor(props) {
		super(props)
		this.state = store.getState()
		this.handleInputChange = this.handleInputChange.bind(this)
		this.handleStoreChange = this.handleStoreChange.bind(this)
		store.subscribe(this.handleStoreChange)
	}
	render() {
		return (
			<div style={{ marginTop: '10px', marginLeft: '10px' }}>
				<div>
					<Input value={this.state.inputValue} placeholder="todo info" 
					style={{ width: '300px' }} 
					onChange={this.handleInputChange}
					/>
					<Button type="primary" onClick={this.handleBtnClick}>Submit</Button>
				</div>
				<List
					style={{ marginTop: '10px', width: '300px' }}
					bordered
					dataSource={this.state.list}
					renderItem={(item, index) => <List.Item onClick={this.handleItemDelete.bind(this, index)}>{item}</List.Item>}
				/>
			</div>
		)
	}
	handleInputChange(e) {
		const action = {
			type: 'change_input_value',
			value: e.target.value
		}
		store.dispatch(action)
	}

	handleStoreChange() {
		this.setState(store.getState())
	}

	handleBtnClick() {
		const action = {
			type: 'add_todo_item'
		}
		store.dispatch(action)
	}

	handleItemDelete(index) {
		const action = {
			type: 'delete_todo_item',
			index
		}
		store.dispatch(action)
	}

}
export default TodoList

reducer.js

const defaultState = {
    inputValue:"hello",
    list :[1, 2]
}
// Reducr accepts state, but never modifies it
export default (state = defaultState, action) =>{
    if (action.type === 'change_input_value') {
        const newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
    }
    if (action.type === 'add_todo_item') {
        const newState = JSON.parse(JSON.stringify(state))
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }
    if (action.type === 'delete_todo_item') {
        const newState = JSON.parse(JSON.stringify(state))
        newState.list.splice(action.index, 1)
        return newState
    }
    return state
}

Source Address
https://gitee.com/thinkerwing/study/tree/master/react_study
Comment on private messages to share video links.

Topics: Front-end React