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
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.