This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

🛰 ️ preface

React is one of the three main front-end frameworks. In real life, react is also preferred by large companies because react’s DIY capabilities are slightly better than those of other frameworks

On the heels of new technology, the react semester began on Monday. React will also be used to implement a TodoList function.

Ding Dong, start the amazing react journey ~🚋

🚀 react basics

Before we design todoList, let’s take a look at some react basics.

1. The introduction of the react

There are some basic things to know about ReactJS:

  • reactjsreact nativereact VR
  • byFacebookLaunched a framework, in2013The year begins in the community;
  • reactRich functional programming;
  • reactIt is currently the most used front-end framework in the world, and it has a well-documented and well-developed community;
  • React FiberReact 16Version, which isReactLots of low-level optimizations.

2. Development environment construction

Before getting into the basics of React, we will first set up the React development environment. There are two ways to set up the React environment:

  • With the introduction of.jsFile to useReact
  • Code with scaffolding tools, for exampleGRUNTGulpwebpack
  • usecreate-react-appTo set up the environment.

So now, let’s build a React project using create-react-app. The command lines are as follows:

npx create-react-app my-app
cd my-app
npm start
Copy the code

3. Project directory file Introduction

After initializing a project, let’s take a look at the React project structure. Details are as follows:

├─ Public ├─ Favicon.ico Web page Icon ├─ index.html Front Page HTML Template ├─ Manifest.json File ├─ SRC ├─ app.css ├─ app.js To fill in the component content ├─ App.test.js Automatic Test file ├─ index.css ├─ index.js Whole program run import file ├─ logo.svg ├─ registerServiceWorker Write mobile App function ├─ README. Md Project Description file ├─ Yarn.lock project dependency install package version numberCopy the code

React basic JSX syntax

We used to write syntax like

in HTML files. So, in React, code of types like

is written in JS. Therefore, HTML code written in JS is called JSX syntax.

It is important to note that when you use your own components in React, the component name must start with a capital letter. Lowercase letters are not supported in JSX.

So, when you see something like
that starts with a capital letter, it means we’ve defined our own component. If it starts with lower case, it is usually a raw HTML5 tag, such as

.

🛸 react TodoList

1. Page design

First, we need to construct the content of the page. Create a file in the project’s SRC folder and name it TodoList. The specific code is as follows:

import React, { Component, Fragment } from 'react';

class TodoList extends Component {
    render() {
        return (
            <Fragment>
            <div>
                <input />
                <button></button>
            </div>
            <ul>
                <li>To learn English</li>
                <li>Learning React</li>
            </ul>
            </Fragment>)}}export default TodoList;
Copy the code

The browser displays the following information:

2. Reactive design and event binding in React

Now that we’ve shown the basic functionality of Todolist, what we want todo is to click the submit button and display the contents of the input box at the bottom of the list.

In our normal thinking, we might expect to bind an event to the submit button, and then, when the bind button is clicked, get the value of the input box and bind the commit.

But in fact, react emphasizes that we don’t want to manipulate the DOM directly, we want to manipulate the data. React automatically senses when our data changes and generates the DOM for us.

Therefore, when writing React, we don’t need to worry about DOM operations, just data operations.

For now, let’s listen for the value of the input box. The specific code is as follows:

import React, { Component, Fragment } from 'react';

class TodoList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            inputValue: 'hello!! '.list: []}}render() {
        return (
            <Fragment>
            <div>
                <input 
                    value = {this.state.inputValue}
                    onChange = {this.handleInputChange.bind(this)}
                />
                <button>submit</button>
            </div>
            <ul>
                <li>To learn English</li>
                <li>Learning React</li>
            </ul>
            </Fragment>)}handleInputChange(e) {
        this.setState({
            inputValue: e.target.value
        })
        
    }
}

export default TodoList;
Copy the code

In this case, the browser prints:

As you can see, we made the input box respond to the data correctly.

So in this code above, there are a few things to know. Respectively is:

  • stateResponsible for storing data in components;
  • If you want to be inhtmlUse some codejsSo remember to use{}To carry a parcel;
  • Remember to use this when doing event bindingbind(this)Change the scope of the event;
  • When you want toChanging data itemsCannot be directly usedthis.stateTo change the value of the data throughsetStateDelta function to change.

3. TodoList can be added and deleted

(1) New functions

In the above example, we implemented the value fetching in the input box. Now, we’re going to implement the submit button to add values to the input field. Again, the changes are made in the todolist.js file. The specific code is as follows:

import React, { Component, Fragment } from 'react';

class TodoList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            inputValue: 'Monday'.list: []}}render() {
        return (
            <Fragment>
            <div>
                <input 
                    value = {this.state.inputValue}
                    onChange = {this.handleInputChange.bind(this)}
                />
                <button onClick={this.handleBtnClick.bind(this)}>submit</button>
            </div>
            <ul>
                {
                    this.state.list.map((item, index) => {
                        return <li key={index}>{ item }</li>})}</ul>
            </Fragment>)}handleInputChange(e) {
        this.setState({
            inputValue: e.target.value
        })
        // console.log(e.target.value)
    }

    handleBtnClick() {
        / /... The expand operator expands the previous array and generates a new array
        // Merge the input box values with the list values to form a new array
        this.setState({
            list: [...this.state.list, this.state.inputValue],
            inputValue: ' '}}})export default TodoList;
Copy the code

The browser displays the following information:

In the above code, some things to know are:

  • We first inbuttonThe binding ofhandleBtnClickEvents;
  • And then by expanding the operator.Merges the contents of the array tolistIn the array;
  • Finally, usejsIn themap()Method to iterate over the contents of the arraylist.

(2) Deletion function

Moving on, let’s implement the delete function. The specific code is as follows:

import React, { Component, Fragment } from 'react';

class TodoList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            inputValue: 'Monday'.list: []}}render() {
        return (
            <Fragment>
                <div>
                    <input
                        value={this.state.inputValue}
                        onChange={this.handleInputChange.bind(this)}
                    />
                    <button onClick={this.handleBtnClick.bind(this)}>submit</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item, index) => {
                            return (
                                <li
                                    key={index}
                                    onClick={this.handleItemDelete.bind(this, index)}
                                >
                                    {item}
                                </li>)})}</ul>
            </Fragment>)}handleInputChange(e) {
        this.setState({
            inputValue: e.target.value
        })
    }

    handleBtnClick() {
        this.setState({
            list: [...this.state.list, this.state.inputValue],
            inputValue: ' '})}handleItemDelete(index) {
        const list = [...this.state.list];
        list.splice(index, 1);

        this.setState({
            list: list
        })
    }
}

export default TodoList;
Copy the code

In the above code, we bind the handleItemDelete event to each

  • tag, and then delete the list by passing its INDEX id and using the splice() method.

  • It’s worth noting that react doesn’t allow us to make any changes to state. For example, we want to write the logic for deleting the code above like this:

    handleItemDelete(index) {
    	this.state.list.splice(index, 1);
        
        this.setState({
            list: this.state.list
        })
    }
    Copy the code

    If we manipulate this directly to change the result, it will make the function difficult to use. React doesn’t allow this either! This is a point to pay attention to!

    🪐 3. Perform advanced operations on TodoList functions

    1. JSX syntax details supplement

    (1) Automatic escape

    If in JSX we want to display something and we want it to escape automatically. It looks like this:

    As you can see, if not escaped, it shows the

    tag removed. But what we really want is to escape it as a level 1 tag. So how do you deal with that?


    We are through dangerouslySetInnerHTML this attribute to set the HTML, has reached the

  • tag to change the content, the specific code is as follows:
  • <li
        key={index}
        onClick={this.handleItemDelete.bind(this, index)}
        dangerouslySetInnerHTML={{ __html: item }}
        >
    </li>
    Copy the code

    Let’s take a look at the display effect:

    By setting dangerouslySetInnerHTML, the content of our HTML is escaped.

    (2) Cursor focus

    In practice, for input boxes, we tend to want to click on some text and have it focus on the input box. So how do you deal with that?

    Let’s move on to the JSX code. The specific code is as follows:

    render() {
            return (
                <Fragment>
                    <div>
                        <label htmlFor="insertArea">The input</label>
                        <input
                            id="insertArea"
                            className="input"
                            value={this.state.inputValue}
                            onChange={this.handleInputChange.bind(this)}
                        />
                        <button onClick={this.handleBtnClick.bind(this)}>submit</button>
                    </div>
                    <ul>
                        {
                            this.state.list.map((item, index) => {
                                return (
                                    <li
                                        key={index}
                                        onClick={this.handleItemDelete.bind(this, index)}
                                        dangerouslySetInnerHTML={{ __html: item }}
                                    >
                                    </li>)})}</ul>
                </Fragment>)}Copy the code

    The browser displays:

    As you can see, when we click on the input words, the cursor automatically focuses on the input box and can type freely. So how does this function work?

    In the above code, we can see that the content is bound with the label tag and htmlFor to achieve the desired effect.

    2. Split value transfer between components

    In a real project, for a large component, we will always split it. That is no exception for the todoList component above.

    We can split the ① input, ② input box and ③ submit button into one component. After that, you split the list into another component. Now let’s split this component and pass data between parent and child components.

    Start by adding a new file in the project’s SRC folder. We’ll call it todoitem.js. The specific code is as follows:

    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); }}export default TodoItem;
    Copy the code

    Now, let’s transform the todolist.js file. The specific code is as follows:

    import React, { Component, Fragment } from 'react';
    import './style.css';
    import TodoItem from './TodoItem';
    
    class TodoList extends Component {
    
        constructor(props) {
            super(props);
            this.state = {
                inputValue: 'Monday'.list: []}}render() {
            return (
                <Fragment>
                    <div>
                        <label htmlFor="insertArea">The input</label>
                        <input
                            id="insertArea"
                            className="input"
                            value={this.state.inputValue}
                            onChange={this.handleInputChange.bind(this)}
                        />
                        <button onClick={this.handleBtnClick.bind(this)}>submit</button>
                    </div>
                    <ul>
                        {
                            this.state.list.map((item, index) => {
                                return (
                                    <div>{/* The parent passes the content, index, and deleteItem to the child */}<TodoItem
                                            content={item}
                                            index={index}
                                            deleteItem={this.handleItemDelete.bind(this)}
                                        />{/ *<li
                                            key={index}
                                            onClick={this.handleItemDelete.bind(this, index)}
                                            dangerouslySetInnerHTML={{ __html: item }}
                                        >
                                        </li>* /}</div>)})}</ul>
                </Fragment>)}handleInputChange(e) {
            this.setState({
                inputValue: e.target.value
            })
            // console.log(e.target.value)
        }
    
        handleBtnClick() {
            / /... The expand operator expands the previous array and generates a new array
            // Merge the input box values with the list values to form a new array
            this.setState({
                list: [...this.state.list, this.state.inputValue],
                inputValue: ' '})}handleItemDelete(index) {
            const list = [...this.state.list];
            list.splice(index, 1);
    
            this.setState({
                list: list
            })
        }
    }
    
    export default TodoList;
    Copy the code

    In this way, we split the component to the same effect as before.

    Now, let’s sort out the knowledge points. There are two main knowledge points:

    • How to split components
    • How should parent components pass values to child components

    First, we create a new file, TodoItem, to hold the contents of the list. That’s number one.

    Second, once we have the contents of the list, we need to think about how data is passed between the parent and child components. In fact, the parent component passes content to the child, in the form of properties. You can see the location of
    in the parent component, where the item is named content with the form Content ={item} and passed to the child component.

    For the child
    , it calls the parent’s data and events as this.props.

    3. TodoList code optimization

    In the above code, we split the components and implemented data transfer between parent and child components.

    But as the observant might have noticed, the code might not be pretty enough. Therefore, let’s optimize the code for these two components.

    The first is todoitem.js. The specific code is as follows:

    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}>
                    {/* {this.props.content} */}
                    {content}
                </div>)}handleClick() {
            const { deleteItem, index } = this.props; deleteItem(index); }}export default TodoItem;
    Copy the code

    We’ll extract this. Props separately and then use it in the component. We also separate out this.handleclick.bind (this) to make the component more aesthetically pleasing.


    Second, let’s transform Todolist.js. The specific code is as follows:

    import React, { Component, Fragment } from 'react';
    import TodoItem from './TodoItem';
    import './style.css';
    
    class TodoList extends Component {
    
        constructor(props) {
            super(props);
            this.state = {
                inputValue: 'Monday'.list: []}this.handleInputChange = this.handleInputChange.bind(this);
            this.handleBtnClick = this.handleBtnClick.bind(this);
            this.handleItemDelete = this.handleItemDelete.bind(this);
        }
    
        render() {
            return (
                <Fragment>
                    <div>
                        <label htmlFor="insertArea">The input</label>
                        <input
                            id="insertArea"
                            className="input"
                            value={this.state.inputValue}
                            onChange={this.handleInputChange}
                        />
                        <button
                            onClick={this.handleBtnClick}
                        >submit</button>
                    </div>
                    <ul>
                        {this.getTodoItem()}
                    </ul>
                </Fragment>)}getTodoItem() {
            // The parent component passes content, index, and deleteItem to the child component
            return this.state.list.map((item, index) = > {
                return (
                    < TodoItem
                        key={index}
                        content={item}
                        index={index}
                        deleteItem={this.handleItemDelete}
                    />
                )
            })
        }
    
        handleInputChange(e) {
            const value = e.target.value;
            this.setState(() = > ({
                inputValue: value
            }));
            // console.log(e.target.value)
        }
    
        handleBtnClick() {
            // prevState specifies what the data is before modifying it, so as not to accidentally change the state
            this.setState((prevState) = > ({
                list: [...prevState.list, prevState.inputValue],
                inputValue: ' '
            }));
        }
    
        handleItemDelete(index) {
            this.setState((prevState) = > {
                const list = [...prevState.list];
                list.splice(index, 1);
                return{ list }; }); }}export default TodoList;
    Copy the code

    Similarly, we first isolate the events handleInputChange, handleBtnClick, and handleItemDelete.

    Second, we isolate this.state.list.map() to form getTodoItem() and call it with {this.getTodoItem()}.

    Finally, we upgrade the this.setState({}) in the event separately to encapsulate all data in the current event in a single function.

    🌠 4. Reflections derived from React

    Above we have basically completed the development of TodoList functionality. Now, we’ll use what we’ve learned to derive some additional knowledge about React. Details are as follows:

    • Declarative development— We used tojsIs a lot of operationsDOMThis type of development is calledImperative development. Up to now, we are usingreactIs basically direct manipulation of data, rather than operationsDOM. So this way of developing is calledDeclarative development.
    • Can coexist with other frameworks
    • Componentized development
    • Unidirectional data flowreactA parent component is allowed to pass a value to a child component, but the child component can only use the value, not change it.
    • View-level framework – helps us deal with data and content on the page, not how values are transferred between components.
    • Functional programming – When a function becomes too much, it can be broken up. Each function does its job, making the code more maintainable. At the same time, it brings great convenience to the front – end automated testing.

    🌌. Conclusion

    In the above article, we learned some basics about React. In addition, we also wrote the basic TodoList and advanced operations. At the same time, we’ve spawned some thoughts around React. React react?

    ✈ ️ eggs

    • Pay attention to the public account Monday laboratory, the first time to pay attention to quality articles, more interview column for you to unlock ~
    • If you think this article is helpful to you, you might as well like to support yo ~~😉
    • That’s all for this article! See you next time! 👋 👋 👋