Preface: What is React? Here’s React.

NPX create-react-app “project name”

React third-party packages

  • classnames
  • Styled – Components Third party package that writes the CSS independently
  • Prop-types: type checking tool for props
  • axios

To write js code in JSX, add a {}

  • Create a simple react:

    import React from "react" import ReactDOM from "react-dom" // const app = <h1>welcome first! </h1> // JSX syntax Const createApp = (props) => {return (<div> {/*}}< h1> <p> Excellent {props. Title}</p> </div>)} const app = createApp({title: }) reactdom.render (app, document.querySelector("#root"))Copy the code

React defines components in this way:

  1. The arrow function capitalizes the first letter of the component
  2. With class components, you can nest them
  • <1> Arrow functions:

    // react creates a component in the first way: Arrow function, Const App = (props) => {return (<div> <h1 title={props. Title}> Want to get a lot of {props. <p> have a lot of {props. Title}</p> </div>)} reactdom.render (<App title=" chicken leg "/>, document.querySelector("#root"))Copy the code
  • <2> Use class inheritance react.component:

    // The second way to define a component: Use class inheritance React.Component import React { Component } from "react" import { render } from "react-dom" class App extends Component { render () { console.log(this.props) //{title: This. Props return (<div> <h1> <p>{this.props. Title}</p> </div>)}} // render Is the method provided by ReactDOM, This method usually only uses render once (<App title=" class component inherits from react.component "/>, Document.queryselector ("#root")) // react.createclass ({// render () {// return (//) <div>{this.props.title}</div> // ) // } // })Copy the code

Components are nested

import React, {Component} from "react" import {render} from "react-dom" const Header = () => <h1> </h1> Class App extends Component { render () { return ( <div> <Header /> <p>{this.props.title}</p> </div> ) } } render( <App />, document.querySelector("#root"))Copy the code
  • JSX creates an element with an infinite number of parameters, but the first two are fixed. The first tag name, the second tag attribute, and the rest are all child elements

React.createElement(type,[props],[…children])

import React, { Component } from "react" import { render } from "react-dom" class App extends Component { render () { return ( React.createElement ( 'div', { className: 'app', id: 'appRoot' }, React.createElement ( 'h1', { className: 'title'}, 'JSX principle'), react. createElement ('p', null, 'jax ') ' ) ) ) } } // const appVDom = { // tag: "div", // attrs: { // className: "app", // id: "appRoot" // }, // children: [/ / {/ / tag: "h1", / / attrs: {/ / the className: "app" / /}, / / the children: / / "JSX principle" / / / /}, {/ / tag: "p", // attrs: null, // children: [/ / / / "JSX exactly how to write?"] / / / / / /}} to render (< App / >, the document. The querySelector (" # root "))Copy the code

The react in the CSS

  1. Create inline using the style tag

    import React, { Component } from "react" import { render } from "react-dom" import classNames from "classnames" import styled from "styled-components" import './index.css' const Title = styled.h2` color: #f00 ` class App extends Component { render () { const style = {color: '#f00'} return (<div> <h1> element style </h1> <Title> Styled - Components using </Title> <ol> <li style={style}> Use style style </li> <li / /li> <li className={classNames('a',{'b': true,'c': False})}> To dynamically add className use classNames third-party package </li>// the li class is only a, }} render(<App />, document.queryselector ("#root"))Copy the code
  2. Use class, but write className, style in CSS file, all import first

Third-party CSS packages: 1. Classnames: dynamically add different classnames

  1. Styled – Components Third party package that writes the CSS independently

React project componentization

RCC React class Component; Function Component of the RFC React

  1. The entry file for the entire one-page App: app.js

  2. Entry file: index.js

  3. The rest of the subcomponent packages are under the App

  4. Create a components directory under SRC that contains all the subcomponents. A subcomponent is a folder with the component name as the folder name. At the same time, there is an index.js file at the root of components, which is used to import and export all child components and import all components in app.js.

  1. Create a services folder under SRC with the apis. Js and index.js files. Apis. Js is a unified management interface file
React todolist: > /your-project > > -src > -... > - components > - YourComponentOne > - index.js/YourComponentOne.js > - YourComponentTwo > - Index. Js/YourComponentTwo. Js > - index. Js to export components Note: A component only does one thing, so TodoList and TodoItem should be made into two components, which is also easy to understand later shouldComponentUpdateCopy the code
  • A return in a component can have only one root element, so react can use either an empty tag or an empty tag

          import React, { Component, Fragment } from 'react'
          import {
              TodoHeader,
              TodoInput,
              TodoList
          } from './components'
          export default class App extends Component {
            render() {
              return (
                <Fragment>
                  <TodoHeader />
                  <TodoInput />
                  <TodoList />
                </Fragment>
      
              //   <>
              //     <TodoHeader />
              //     <TodoInput />
              //     <TodoList />
              //   </>
              )
            }
          }
    Copy the code

There are two export methods:

// Import TodoHeader from './TodoHeader' // import TodoInput from './TodoInput' // import TodoList from './TodoList' // export { // TodoHeader, // TodoInput, // TodoHeader export {default as TodoHeader} from './TodoHeader' export {default as TodoInput} from ' './TodoInput' export { default as TodoList} from './TodoList'Copy the code

How to mount data of a component

  1. Pass through props

The function component is passed directly through props. XXX, and the class component is passed through this.props. XXX

	    import React from 'react'
	
	    export default function TodoHeader(props) {
	      console.log(props)// {title: "待办事项"}
	      return (
	        <h1>
	          {props.title}
	        </h1>
	      )
	    }
Copy the code

Properties (props)

The contents of the props. Children component tag

// app.js export default class extends Component {render() {return (<Fragment> <TodoHeader desc=" do all things today "> TodoHeader> <TodoInput btnText="ADD"/> <TodoList /> </Fragment> // TodoHeader/index.js export default function TodoHeader(props) {console.log(props) // {desc: "Do everything today ", children: "To-do list "} return (<h1> {props. Children} </h1>)}Copy the code
  • Prop-types: type checking tool for props

          // TodoHeader/index.js
          import React from 'react'
          import PropTypes from 'prop-types'
          export default function TodoHeader(props) {
            console.log(props)
            return (
              <>
                <h1>
                  {props.children}
                </h1>
                <h3>{props.desc}</h3>
                <p>{props.x + props.y}</p>
              </>
            )
          }
          TodoHeader.propTypes = {
            desc: PropTypes.string,
            x: PropTypes.number.isRequired,
            y: PropTypes.number.isRequired
          }
    Copy the code
  • Class component:

    // TodoInput.js import React, { Component } from 'react' import PropTypes from 'prop-types' export default class TodoInput extends Component { static propTypes = { btnText: PropTypes.string } static defaultProps = { btnText: 'add TODO / / component default value} / / TodoHeader defaultProps = {/ / desc: Render () {return (<div> <input type="text"/><button>{this.props. BtnText}</button> </div>) }}Copy the code

state

The internal state of a component is defined using state, and there are two ways to define it, while props is a property passed in externally. Only class components have this and state

// app.js export default class App extends Component {// state = {// title: Constructor () {super() this.state = {title: 'todo ', desc: constructor () {super() this.state = {title:' todo ', desc: } render() {return (<Fragment> <TodoHeader desc={this.state.desc}> {this.state.title} </TodoHeader>Copy the code

Classification of components:

  • Class components and Function components

  • A controlled component, an uncontrolled component, or a semi-controlled component (passed through the props property, which cannot be modified internally within the component is called a controlled component, and the state defined through state is not an external passed uncontrolled component)

  • Props cannot be passed across components; they must be passed layer by layer

  • Component template rendering syntax

    {/* {this.todos[0].isCompleted && 'completed '} */} {this.state.todos[0].iscompleted? 'done' : Todo.map (todo => {return <div key={todo.id}>{todo.title}</div>})} {div DangerouslySetInnerHTML ={{__html: this.state.article}}} // Render content without HTML tagsCopy the code

DangerouslySetInnerHTML, similar to Vue’s V-HTML, outputs content without HTML tags

Properties vs states

  • Similarities: Both pure JS objects, both trigger render updates, both deterministic (same state/property, same result)

  • Difference:

Properties can be obtained from the parent component, but the status cannot be 2. Properties can be modified by the parent component, but the status cannot be 3. Properties can be set internally to default values, and the state can also be set to 4. Properties are not modified internally by the component; the state is changed to 5. The property can set the initial value of the subcomponent, but the status cannot. 6. The property can change the value of the subcomponent, but the status cannot

  • The primary purpose of state is for components to save, control, and modify their mutable state. State is initialized within a component and can be modified by the component itself, but cannot be accessed or modified externally. You can think of state as a local data source that can only be controlled by the component itself. The state in state can be updated with the this.setState method, which causes the component to be rerendered.

  • The main purpose of the props is to allow the parent component that uses the component to pass in parameters to configure the component. It is a configuration parameter that is passed in externally and cannot be controlled or modified internally by the component. The props of a component are always the same unless the external component actively passes in new props.

  • If you’re confused about how to use state and props, remember a simple rule: use less state and more props.

  • A component that has no state is a stateless component, and a component that has state set is a stateful component. Because of the complexity of state management, we write as many stateless components as possible and as few stateful components as possible. This will reduce the difficulty of maintaining the code and increase the reusability of components to some extent.

Change state (setState)

  • React cannot be used directly with this.state. XXX =! This.state.xxx to change the state directly, using the setSate() method. (Data can be modified, but the page will not render)

  • SetState () takes two arguments. The first argument can be an object. The second case is a method.

  • The second argument to setState is a callback in which to return an object. Since setState is asynchronous, the latest state must be retrieved in the callback of the second argument

  • React’s setState is asynchronous, and methods in setState are executed later than methods outside of it

    import React, { Component } from 'react' export default class Like extends Component { constructor () { super() this.state = { IsLiked: false}} likedClick = () => {// isLiked: false}} likedClick = () => {// isLiked:! This.state. IsLiked //}) PrevState (prevState) => {console.log(prevState) return {isLiked:! Prevstate. isLiked}}, () => {// setState is asynchronous, Render (· <div> <span onClick={this.likedclick}> {console.log(this.state)})} render() {return (· <div> <span onClick={this.likedclick}> { this.state.isLiked ? 'Too bad! 👍' : 'Awesome! 👎'} </span> </div>)}}Copy the code

The react event

To change the value in state, use the onChange event (which is humped) and then use the setState method to change the value, otherwise it cannot be entered on the page

// TodoInput/index.js import React, { Component } from 'react' import PropTypes from 'prop-types' export default class TodoInput extends Component { static propTypes = { btnText: PropTypes.string } static defaultProps = { btnText: } constructor () {super() this.state = {inputValue: 'xxx' } // this.addTodo = this.addTodo.bind(this) } onInputChange = (e) => { this.setState({ inputValue: e.currentTarget.value }) } addTodo = (id) => { console.log(this.state,id) } render() { return ( <div> <input type="text"  onChange={this.onInputChange} value={this.state.inputValue}/> <button onClick={this.addTodo.bind(this,1234)}>{this.props.btnText}</button> </div> ) } } // App.js addItem = (todoTitle) => { Console. log(todoTitle) // this.setState({// // adds the first method to todo, not push, push returns the length of the array // todos: this.state.todos.concat({ // id: Math.random(), // title: todoTitle, // isCompleted: // Const newTodos = this.state.todos.slice() const newTodos = [...this.state.todos] newTodos.push({ id: Math.random(), title: todoTitle, isCompleted: false }) this.setState({ todos: newTodos }) }Copy the code

React uses ref to get components or DOM elements. To use ref, call React. CreateRef to create a ref.

import React, { Component, createRef } from 'react' import PropTypes from 'prop-types' export default class TodoInput extends Component { static propTypes = { btnText: PropTypes.string } static defaultProps = { btnText: } constructor () {super() this.state = {inputValue: "'} / / this. AddTodo = this. AddTodo. Bind (this) / / in the constructor to create ref enclosing inputDom = createRef ()} onInputChange = (e) => { this.setState({ inputValue: e.currentTarget.value }) } addKeyUp = (e) => { if(e.keyCode === 13){ // console.log(e) this.addTodo() } } addTodo = () => { if(this.state.inputValue === ''){ return } console.log(this.inputDom) this.props.addItem(this.state.inputValue) this.setState({ inputValue: "'}, () => { this.inputDom.current.focus() }) } render() { return ( <div> <input type="text" onChange={this.onInputChange} onKeyUp={this.addKeyUp} value={this.state.inputValue} ref={this.inputDom}/> <button onClick={this.addTodo}>{this.props.btnText}</button> </div> ) } }Copy the code