React builds JavaScript libraries for user interfaces, primarily for building UI interfaces.Instagram, Open Source, 2013.
Characteristic:
- Declarative design
- Efficient, uses virtual DOM to render DOM, minimizing DOM operations.
- Flexible to use with other libraries.
- JSX, commonly known as JS, writes HTML inside, an extension of JavaScript syntax.
- Componentized, modular.Code is easy to reuse, large projects like react very much before 2016
- One-way data stream.Two-way binding of data is not implemented.Data - "View -"Events - "Data
Create Project
1. Use by script, only for learning debugging
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
2. Create projects for development and deployment through react scaffolding
1. Install scaffolding Create React App. cnpm install -g create-react-app 2. Create Project create-react-app 01reactapp(Project name can be customized)
React Element Rendering
let h1 = <h1>helloworld</h1>; JS element objects can be created using JSX notation Note: JSX element objects, or component objects, must have only one root element (root node)
Case use:
//Display page moments function clock(){ let time = new Date().toLocaleTimeString() let element = ( <div> <h1>The time is now{time} </h1> <h2>This is the subtitle</h2> </div> ) let root = document.querySelector('#root'); ReactDOM.render(element,root) } clock() setInterval(clock,1000)
Functional Component Rendering
function Clock(props){ return ( <div> <h1>The time is now{props.date.toLocaleTimeString()} </h1> <h2>This is functional component development</h2> </div> ) } function run(){ ReactDOM.render( <Clock date={new Date()} />, document.querySelector('#root') ) } setInterval(run,1000)
React Jsx
Advantage:
- JSX executes faster and is optimized when compiled into JavaScript code
- Type is safer, compilation process cannot compile if there are errors, timely error detection
- JSX is easier and faster to write templates.(Do not compare with VUE)
Be careful:
- JSX must have a root node.
- Normal normal HTML elements are lowercase.If capitalized, components are considered by default.
JSX expression
- Composed of HTML elements
- Use {} if you need to insert a variable in the middle
- An expression can be used in the middle of {}
- {} JSX objects can be used in intermediate expressions
- Properties are inserted with {} just like html content
case
import React from 'react'; import ReactDOM from 'react-dom'; import './App.css' let time = new Date().toLocaleTimeString() let str = 'The current time is:' let element = ( <div> <h1>helloworld</h1> <h2>{str+time}</h2> </div> ) console.log(element) let man = 'fever'; let element2 = ( <div> <h1>Is it quarantined today</h1> <h2>{man=="fever"?<button>quarantine</button>:"On the bed"}</h2> </div> ) //let man ='fever'; let element4 = ( <div> <span>Lie on your back</span> <span>Lie upright</span> </div> ) man = 'normal' let element3 = ( <div> <h1>Is it quarantined today</h1> <h2>{man=="fever"?<button>quarantine</button>:element4}</h2> </div> ) let color = 'bgRed' let logo = 'https://www.baidu.com/img/pc_1c6e30772d5e4103103bd460913332f9.png' //HTML style class names are written as className because class is the key word in js let element5 = ( <div className={color}> <img src={logo} /> //Red background color </div> ) ReactDOM.render( element5, document.getElementById('root') )
JSX_style style
- Class, style, cannot have more than one class attribute
- In style, if there is an attribute combination of more than one word, the second word begins with the first letter capitalized.Or use quotation marks, otherwise an error will be made.
let exampleStyle = { background:"skyblue", borderBottom:"4px solid red", 'background-image':"url(https://www.baidu.com/img/pc_1c6e30772d5e4103103bd460913332f9.png)" }
3. Operations where multiple classes coexist
let element2 = ( <div> <h1 className={"abc "+classStr}>helloworld</h1> </div> ) let classStr2 = ['abc2','redBg2'].join(" ") let element3 = ( <div> {/* Note here */} <h1 className={classStr2} style={exampleStyle}>helloworld</h1> </div> )
4. Notes
Must be written in parenthesized expressions, otherwise error: {/* Comment here */}
React Component
Functional components differ from class components in that they are simple to use and are generally used for static component pages without interactive event content.Class components, also known as dynamic components, generally have interactive or data modification operations.
- Functional Component
//Functional Component function Childcom(props){ console.log(props) let title = <h2>I am the subtitle</h2> let weather = props.weather //Conditional Judgment let isGo = weather=='rain' ?"Don't go out":"go out" return ( <div> <h1>Functional Component helloworld</h1> {title} <div> //Do you want to go out? <span>{isGo}</span> </div> </div> ) }
2. Class Components
//Class Component Definition class HelloWorld extends React.Component{ render(){ console.log(this) return ( <div> <h1>Class Component Definition HELLOWORLD</h1> <h1>hello:{this.props.name}</h1> <Childcom weather={this.props.weather} /> </div> ) } }
3. Composite components: Components have other components, which can have both class components and function components.
import React from 'react'; import ReactDOM from 'react-dom'; import './04style.css'; //Functional Component function Childcom(props){ console.log(props) let title = <h2>I am the subtitle</h2> let weather = props.weather //Conditional Judgment let isGo = weather=='rain' ?"Don't go out":"go out" return ( <div> <h1>Functional Component helloworld</h1> {title} <div> //Do you want to go out? <span>{isGo}</span> </div> </div> ) } //Class Component Definition class HelloWorld extends React.Component{ render(){ console.log(this) //All returned are JSX objects return ( <div> <h1>Class Component Definition HELLOWORLD</h1> <h1>hello:{this.props.name}</h1> <Childcom weather={this.props.weather} /> </div> ) } } // ReactDOM.render( // <Childcom weather="sunrise"/>, // document.querySelector('#root') // ) ReactDOM.render( <HelloWorld name="Old Chen" weather="rain" />, document.querySelector('#root') )
React State
ATA equivalent to VUE, but not in the same way as VUE.
Props
Parent to child component data, one-way flow, cannot child to parent.
The props can be of any type.
Props can set default values
HelloMessage.defaultProps = {name:"Chen", msg: "helloworld"}
Note: props can pass functions, props can pass functions of the parent element, and can modify the state of the parent element to pass data to the parent element.
Parent to Child
//Use state in parent elements to control props of child elements so that parent element data is passed to child elements class ParentCom extends React.Component{ constructor(props){ super(props) this.state = { isActive:true } //Binding Events this.changeShow = this.changeShow.bind(this) } render(){ return ( <div> <button onClick={this.changeShow}>Control child element display</button> <ChildCom isActive={this.state.isActive} /> </div> ) } changeShow(){ this.setState({ isActive:!this.state.isActive }) } } class ChildCom extends React.Component{ constructor(props){ super(props) } render(){ let strClass = null; if(this.props.isActive){ strClass = ' active' }else{ strClass = "" } strClass = this.props.isActive?" active":""; return ( <div className={"content"+strClass}> <h1>I am a child element</h1> </div> ) } }
Child passed to parent
class Parent extends React.Component { constructor(props) { super(props) this.state = { childData: null } } render() { return ( <div> <h1>Data passed from child elements to parent elements:{this.state.childData}</h1> {/* Pass the method of setting the parameter through props to the child element */} <Child setChildData={this.setChildData}/> </div> ) } setChildData=(data)=>{ this.setState({ childData:data }) } } class Child extends React.Component{ constructor(props){ super(props) this.state={ msg:"helloworld" } } render(){ return( <div> <button onClick={this.senData}>Pass to parent element</button> //With ES6, you can write arrow function arguments directly in button events <button onClick={()=>{this.props.setChildData("666")}}>Pass to parent element</button> //Without ES6, <button onClick={function(e){this.props.setChildData("666")}.bind(this)}>Pass to parent element</button> </div> ) } //Unbound events can use the arrow function directly senData=()=>{ //Method passes arguments in props passed from parent element this.props.setChildData(this.state.msg) } }
Event
Characteristic:
1. react events, naming of binding events, hump naming.
2, {}, passing in a function instead of a string
<button onClick={this.sendData}>Pass helloworld to parent element</button>
Event object: The event object returned by React is the agent's native event object. If you want to see the specific value of the event object, you must output the properties of the event object between them.
Be careful:
Native, return false can be returned directly when default behavior is blocked;
In React, the blocking default must be e.preventDefault();
React event pass parameters
{/* Passing multiple parameters using the ES6 arrow function */} <button onClick={(e)=>{this.parentEvent1('msg:helloworld',e)}}>Submit</button> {/* //How to pass multiple parameters without using the ES6 arrow function */} <button onClick={function(e){this.parentEvent1('Do not use es6,msg:helloworld',e)}.bind(this)}>Submit</button>
conditional rendering
1. Return JSX objects to render directly through conditional operations
2. The JSX object is obtained by conditional operation and rendered into the template.
Case 1
function UserGreet(props){ return (<h1>Welcome to login</h1>) } function UserLogin(props){ return (<h1>Please login first</h1>) } class ParentCom extends React.Component{ constructor(props){ super(props) this.state = { isLogin:true } } render(){ if(this.state.isLogin){ return (<UserGreet></UserGreet>) }else{ return (<UserLogin></UserLogin>) } } }
Case 2
function UserGreet(props){ return (<h1>Welcome to login</h1>) } function UserLogin(props){ return (<h1>Please login first</h1>) } class ParentCom extends React.Component{ constructor(props){ super(props) this.state = { isLogin:false } } render(){ let element = null; if(this.state.isLogin){ element = <UserGreet></UserGreet>; }else{ element = (<UserLogin></UserLogin>); } return ( <div> <h1>This is the head</h1> {element} <h1>This is the operation of a ternary operator</h1> {this.state.isLogin?<UserGreet></UserGreet>:<UserLogin></UserLogin>} <h1>This is the tail</h1> </div> ) } }
List Rendering
Put the list contents into an array and place them in a template.JSX object that assembles data into an array.
Using the map method of arrays, each item of data is processed as JSX, resulting in an array where each item is a JSX object and rendered into a template.
The Key value needs to be placed in each item.
Case 1
class Welcome extends React.Component{ constructor(props){ super(props) this.state = { list:[ { title:"Section 1 React Event", content:"Event Content" }, { title:"Section 2 React Data Transfer", content:"Data Transfer Content", }, { title:"Section 3 Conditional Rendering", content:"Conditional Rendering Content", } ] } } render(){ let listArr = []; for(let i=0;i<this.state.list.length;i++){ let item = ( <li> <h3>{this.state.list[i].title}</h3> <p>{this.state.list[i].content}</p> </li> ) listArr.push(item) } return ( <div> <h1> //Today's course content </h1> <ul> {listArr} <li> <h3>This is the title</h3> <p>content</p> </li> </ul> </div> ) } }
Case 2
function ListItem(props){ return ( <li> <h3>{props.index+1}:listItem:{props.data.title}</h3> <p>{props.data.content}</p> </li> ) } class ListItem2 extends React.Component{ constructor(props){ super(props) } render(){ return ( <li onClick={(event)=>{this.clickEvent( this.props.index, this.props.data.title, event )}}> <h3>{this.props.index+1}:listItem:{this.props.data.title}</h3> <p>{this.props.data.content}</p> </li> ) } clickEvent=(index,title,event)=>{ alert((index+1)+"-"+title) } } class Welcome extends React.Component{ constructor(props){ super(props) this.state = { list:[ { title:"Section 1 React Event", content:"Event Content" }, { title:"Section 2 React Data Transfer", content:"Data Transfer Content", }, { title:"Section 3 Conditional Rendering", content:"Conditional Rendering Content", } ] } } render(){ let listArr = this.state.list.map((item,index)=>{ return ( <ListItem2 key={index} data={item} index={index}></ListItem2> ) }) return ( <div> <h1> //Today's course content </h1> <ul> {listArr} <li> <h3>This is the title</h3> <p>content</p> </li> </ul> <h1>Complex not complete list with component</h1> <ul> { this.state.list.map((item,index)=>{ return ( <li key={index} onClick={(event)=>{this.clickFn(index,item.title,event)}}> <h3>{index+1}-complex-{item.title}</h3> <p>{item.content}</p> </li> ) }) } </ul> </div> ) } clickFn=(index,title,event)=>{ alert((index+1)+"-clickFn-"+title) } }
life cycle
The life cycle is the component from instantiation to rendering to final destruction from the page, and the whole process is the life cycle. In this life cycle, we have many events that can be called, also known as hook functions.
Three states of the life cycle:
Mounting: Insert components into DOM
Updating: Update data to DOM
Unmounting: Remove components from DOM
Hook functions in the life cycle (methods, events)
CompontWillMount: Component will render, AJAX, add pre-animation classes
CompontDidMount: Component rendering complete, add animation
compontWillReceiveProps: Components will accept props data to see what data they receive
ShouldComponentUpdate: The component receives a new state or props to determine if it is updated.Return Boolean
CompontWillUpdate: Components will be updated
ComponentDidUpdate: Component has been updated
ComponentwillUnmount: Component will be uninstalled
React slot
Writes in the organization that can be identified and controlled.React needs to develop its own support slot function.
Principle:
HTML written in the component can be passed into props.
Insert all HTML content directly into the component
Insert all HTML content directly into the component
class ParentCom extends React.Component{ render(){ console.log(this.props) return ( <div> <h1>Component slot</h1> {this.props.children} </div> ) } }
Components insert in different locations depending on the HTML content.
import React from 'react'; import ReactDOM from 'react-dom'; class ParentCom extends React.Component{ render(){ console.log(this.props) return ( <div> <h1>Component slot</h1> {this.props.children} <ChildCom> <h1 data-position="header">This is the content placed on the head</h1> <h1 data-position="main">This is where you put the main content</h1> <h1 data-position="footer">This is what you put at the end</h1> </ChildCom> </div> ) } } class ChildCom extends React.Component{ render(){ let headerCom,mainCom,footerCom; this.props.children.forEach((item,index)=>{ if(item.props['data-position']==='header'){ headerCom = item }else if(item.props['data-position']==='main'){ mainCom = item }else{ footerCom = item } }) return ( <div> <div className="header"> {headerCom} </div> <div className="main"> {mainCom} </div> <div className="footer"> {footerCom} </div> </div> ) } } class RootCom extends React.Component{ constructor(props){ super(props) //console.log(props) this.state = { arr:[1,2,3] } } render(){ return ( <ParentCom> <h2 data-name="a" data-index={this.state.arr[0]}>Sub-systems</h2> <h2 data-name="b" data-index={this.state.arr[1]}>Subcomponent 2</h2> <h2 data-name="c" data-index={this.state.arr[2]}>Subcomponent 3</h2> </ParentCom> ) } } ReactDOM.render( <RootCom></RootCom> , document.querySelector("#root") )
React Routing
Display different components (content) according to different paths; React uses the library react-router-dom;
install
Cnpm install react-router-dom --save
Three components of ReactRouter:
Router: The root component (the underlying component) of all routing components that encapsulates the outermost container of routing rules.
Property: basename->Set the root path with which the router can write more than one component.
Route: Routing rule matching component, displaying the component corresponding to the current rule
Link: Component of Route Jump
Note: If you want an exact match, you can set the exact property on the route.
Router use cases
import React from 'react'; //hash mode //import {HashRouter as Router,Link,Route} from 'react-router-dom' //Hisry Mode/Backend Matching Usage import {BrowserRouter as Router,Link,Route} from 'react-router-dom' function Home(){ return ( <div> <h1>admini home page</h1> </div> ) } function Me(){ return ( <div> <h1>admin Personal Center</h1> </div> ) } function Product(){ return ( <div> <h1>admin Product Page</h1> </div> ) } class App extends React.Component{ render(){ return ( <div id="app"> {/* <div>Normal Content for All Pages </div> */} <Router> <Route path="/" exact component={()=>(<div>home page</div>)}></Route> <Route path="/me" component={()=>(<div>me</div>)}></Route> <Route path="/product" component={()=>(<div>product</div>)}></Route> </Router> <Router> {/* <div className="nav"> <Link to="/">Home</Link> <Link to="/product">Product</Link> <Link to="/me">Personal Center </Link> </div> */} <Route path="/admin/" exact component={Home}></Route> <Route path="/admin/product" component={Product}></Route> <Route path="/admin/me" exact component={Me}></Route> </Router> </div> ) } } export default App
The Link component can set the to property to jump pages. The to property can either write a string of paths directly or set paths through an object, such as
render(){ let meObj = { pathname:"/me",//Jump Path search:"?username=admin",//get request parameters hash:"#abc ", //set HASH value state:{msg:'helloworld'}//Data passed in to the component }; return ( <div id="app"> <Router> <div className="nav"> <Link to="/">Home</Link> <Link to="/product">Product</Link> <Link to={ meObj }>Personal Center</Link> </div> <Route path="/" exact component={Home}></Route> <Route path="/product" component={Product}></Route> <Route path="/me" exact component={Me}></Route> </Router> </div> ) }
Link's replace property: After clicking the link, replace the new address with the original address of the historical access record.
Dynamic routing implementation:
import React from 'react'; //hash mode //import {HashRouter as Router,Link,Route} from 'react-router-dom' //Hisry Mode/Backend Matching Usage import {BrowserRouter as Router,Link,Route} from 'react-router-dom' function Home(){ return ( <div> <h1>admini home page</h1> </div> ) } function Me(props){ console.log(props) return ( <div> <h1>admin Personal Center</h1> </div> ) } function Product(){ return ( <div> <h1>admin Product Page</h1> </div> ) } function News(props){ console.log(props) return ( <div> //News page, news id: {props.match.params.id} </div> ) } class App extends React.Component{ render(){ let meObj = { pathname:"/me",//Jump Path search:"?username=admin",//get request parameters hash:"#abc ", //set HASH value state:{msg:'helloworld'}//Data passed in to the component }; return ( <div id="app"> <Router> <div className="nav"> <Link to="/">Home</Link> <Link to="/product">Product</Link> <Link to={ meObj } replace>Personal Center</Link> <Link to="/news/4568789">News Page</Link> </div> <Route path="/" exact component={Home}></Route> <Route path="/product" component={Product}></Route> <Route path="/me" exact component={Me}></Route> <Route path="/news/:id" component={News}></Route> </Router> </div> ) } } export default App
Redirect Component
If a component is accessed and there is a redirect component, the page path is modified so that the page content is displayed as the content of the directed path
Use case:
function LoginInfo(props){ //props.loginState = 'success'; //props.loginState = "fail" console.log(props) if(props.location.state.loginState === 'success'){ return <Redirect to="/admin"></Redirect> }else{ return <Redirect to="/login"></Redirect> } }
Switch Component
Let the route of the switch component content match only one, and if it does, the remaining routing rules will no longer match
class App extends React.Component{ render(){ return ( <div> <Router> <Switch> <Route path="/" exact component={()=>(<h1>home page</h1>)}></Route> <Route path="/form" exact component={FormCom}></Route> <Route path="/login" exact component={()=>(<h1>Logon Page</h1>)}></Route> <Route path="/logininfo" exact component={LoginInfo}></Route> <Route path="/admin" exact component={()=>(<h1>admin page,Login Successful</h1>)}></Route> <Route path="/abc" exact component={()=>(<h1>abc1 page,Login Successful</h1>)}></Route> <Route path="/abc" exact component={()=>(<h1>abc2 page,Login Successful</h1>)}></Route> </Switch> </Router> </div> ) } }
Redux
Resolves React data management (state management), which is used for medium and large size, large data size, and large data interaction between components.If you don't know if you need Redux, then you don't need it!
* Resolve data communication for components.
* Solve applications with more data and interaction
Redux is just a state management solution!
Store: Data warehouse, where data is stored.
State:state is an object, and all data in the data warehouse is placed in a state.
Action: An action, the method by which data changes are triggered.
Dispatch: Triggers an action into a method
Reducer: is a function that generates a new state by taking actions and changing data.To change the page
install
Cnpm install redux --save
Initialize data
//Create warehouse const store = createStore(reducer) //Used to create a new state by an action //reduce has two functions, one to initialize the data and the other to change the data by taking actions const reducer = function(state={num:0},action){ console.log(action) switch(action.type){ case "add": state.num++; break; case 'decrement': state.num--; break; default: break; } return {...state}//COPY equivalent to object }
get data
let state = store.getState()
Modify Data (Modify Data by Action)
//Modify data through the warehouse method dispatch store.dispatch({type:"add",content:{id:1,msg:"helloworld"}})
Modify the view (listen for data changes, re-render content)
store.subscribe(()=>{ ReactDOM.render(<Counter></Counter>,document.querySelector("#root")) })
Complete case
import React from 'react'; import ReactDOM from 'react-dom'; import {createStore} from 'redux' //Used to create a new state by an action const reducer = function(state={num:0},action){ console.log(action) switch(action.type){ case "add": state.num++; break; case 'decrement': state.num--; break; default: break; } return {...state}//COPY equivalent to object } //Create warehouse const store = createStore(reducer) console.log(store) function add(){ //Modify data through the warehouse method dispatch store.dispatch({type:"add",content:{id:1,msg:"helloworld"}}) console.log(store.getState()) } function decrement(){ //Modify data through the warehouse method dispatch store.dispatch({type:"decrement"}) console.log(store.getState()) } //Functional counters const Counter = function(props){ //console.log(store.getState()) let state = store.getState() return ( <div> <h1>Count quantity:{state.num}</h1> <button onClick={add}>count+1</button> <button onClick={decrement}>count-1</button> </div> ) } ReactDOM.render(<Counter></Counter>,document.querySelector("#root")) store.subscribe(()=>{ ReactDOM.render(<Counter></Counter>,document.querySelector("#root")) })
React-redux
install
cnpm install react-redux --save
Concepts:
Provider component: Automatically associates the state in the store with the component.
MapStatetoProps: This function maps the store state to the props in the component
mapdispatchToProps: Maps dispatches in store s to props of components to share methods.
Connect method: Connect components to data (methods)
Use:
Initialize data, instantiate store
function reducer(state={num:0},action){ switch(action.type){ case "add": state.num++; break; default: break; } return {...state} } const store = createStore(reducer)
Data acquisition, data modification
To map a state to a component's props, map methods that modify data to the component's props
Complete case
import React from 'react'; import ReactDOM from 'react-dom'; import {createStore} from 'redux'; import {connect, Provider} from 'react-redux' class Counter extends React.Component{ render(){ console.log(this.props) //Count, passed to props through stroe's state, and get state's data directly through props const value = this.props.value; //Pass events or methods that modify data into props const onAddClick = this.props.onAddClick; //mapMutation mapState equivalent to vuex return ( <div> <h1>Number of counts:{value}</h1> <button onClick={onAddClick}>number+1</button> <button onClick={this.props.onAddClick5}>number+5</button> </div> ) } } let ActionFnObj={ add:function(state,action){ state.num++ return state }, addNum:function(state,action){ state.num = state.num + action.num; return state } } function reducer(state={num:0},action){ if(action.type.indexOf('redux')===-1){ state = ActionFnObj[action.type](state,action) return {...state} }else{ return state; } } const store = createStore(reducer) //Map state to props function function mapStateToProps(state){ return { value:state.num } } const addAction = { type:'add' } //The method that modifies the state data is mapped to props, which is passed into the dispach method in the store by default function mapDispatchToProps(dispatch){ return { onAddClick:()=>{dispatch(addAction)}, onAddClick5:()=>{dispatch({type:"addNum",num:5})} } } //Map the two methods above to the components, the state of the data warehouse and the method of modifying the state, to form new components. const App = connect( mapStateToProps, mapDispatchToProps )(Counter) ReactDOM.render( <Provider store={store}> <App></App> </Provider>, document.querySelector("#root") )
Ant Ant Frame
npm install antd-mobile --save
Import as needed (automatically import the css styles used):
- Install Plugins
npm install babel-plugin-import --save
2. Configuration
npm run eject
3.Packjson file
"babel": { "presets": [ "react-app" ], "plugins": [ ["import", { "libraryName": "antd-mobile", "style": "css" }] ] }
Remaining Reference Officials