5, React -- List & Key, form

Keywords: React

List & key

1, Use of. map()

1. List components of rendering basis

This component takes the numbers array as a parameter and outputs a list of elements.

const numbers = [1,2,3,4,5]
function NumList(props){
    const numbers = props.numbers;
    const listItems = numbers.map((number)=>(
        <li>number:{number}</li>
    ));
    return (
        <ul>
            {listItems}    
        </ul>
    )
}
const app = <NumList numbers={numbers} />
ReactDOM.render(app, document.querySelector(".app"))


When we run the above code, we will be warned that each node in the list must have an independent Key attribute

2. Function and usage of key

key helps React identify which elements have changed, such as being added or deleted. Therefore, you should give each element in the array a definite identity.

const numbers = [1,2,3,4,5]
function NumList(props){
    const numbers = props.numbers;
    // 01- key helps React identify which elements have changed, such as being added or deleted. Therefore, you should give each element in the array a definite identity.
    // const listItems = numbers.map((number)=>(
    //     <li key={number.toString()}>id1:{number}--{number.toString()}</li>
    // ));
    
    // 02 - the key of an element should preferably be a unique string owned by the element in the list. Usually, we use the id in the data as the key of the element
	// const listItems = numbers.map((number)=>(
    //     <li key={number.id}>number:{number}--{number.id}</li>
    // ));

    // 03 - when the element has no id, you can use the element index as the key as a last resort:
    const listItems = numbers.map((number,index)=>(
        <li key={index}>id2:{number}--{index}</li>
    ));
    return (
        <ul>
            {listItems}    
        </ul>
    )
}
const app = <NumList numbers={numbers} />
ReactDOM.render(app, document.querySelector(".app"))

2, Extract components with key

1. The key of an element is meaningful only when it is placed in the nearest array context.

For example, if you extract a ListItem component, you should keep the key on the element in the array instead of the < li > element in the ListItem component. (the key is placed wherever the map is.)

2. The key must only be unique among sibling nodes
The key used in the array element should be unique among its sibling nodes.
However, they do not need to be globally unique. When we generate two different arrays, we can use the same key value.

For details, refer to the following examples:

const posts = [
    { id: 1, title: 'Hello World', content: 'Welcome to learning React!' },
    { id: 2, title: 'Installation', content: 'You can install React from npm.' }
];
function PostList(props) {
    // The element's key is meaningful only when it is placed in the context of the adjacent array
    const title = (
        <ul>
            {props.posts.map((post) => (
                <li key={post.id}>{post.title}</li>
            ))}
        </ul>
    )
    // The key s between sibling nodes must be unique (sibling nodes are all sibling nodes during array traversal)
    // Global can not be unique
    const content = (
        props.posts.map((post) => {
            return <Content {...post} key={post.id} />
        })
    )
    return (
        <ul>
            <Title posts={props.posts} />
            <hr />
            {content}
        </ul>
    )
}
function Title(props) {
    return (
        <ul>
            {props.posts.map((post) => (
                <li key={post.id}>{post.title}</li>
            ))}
        </ul>
    )
}
function Content(props) {
    const { id, title, content } = props
    return (
        <div>
            <h1>{id}</h1>
            <h1>{title}</h1>
            <h3>{content}</h3>
        </div>
    )
}
const app = <PostList posts={posts} />
ReactDOM.render(app, document.querySelector(".app"))

form

In React, HTML form elements work differently from other DOM elements because form elements usually maintain some internal state s. For example, this pure HTML form accepts only one name:

<form>
  <label>
    name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

This form has the default HTML form behavior, that is, browse to a new page after the user submits the form. If you execute the same code in React, it still works. However, in most cases, the use of JavaScript functions can facilitate the submission of forms and access the form data filled in by users. The standard way to achieve this effect is to use "controlled components".

Controlled components

1. In HTML, form elements such as < input >, < textarea > and < Select >) usually maintain their own state and update according to user input. In React, mutable state is usually saved in the state attribute of the component and can only be updated by using setState().

2. We can combine the two to make React's state the "only data source". The React component of the rendered form also controls what happens to the form during user input. The form input elements whose values are controlled by React in this way are called "controlled components".

3. props with value specified on the controlled component will prevent the user from changing the input. If you specify value but the input can still be edited, you may accidentally set value to undefined or null.
However, when your value can be updated by setState, it can become editable again

// Bidirectional data binding
/*
    Analog vue
    Data - > page: attribute binding value attribute binding status data 
    value={this.state.username}

    Page - > data: event binding onchange - > custom event changehandle - > setstate - > State 
    onChange={this.handleChange} 
*/
class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            username: "mikasa",
            age: 18,
            single: "false",
            desc: "no bad",
            hobby: "paly"
        }
    }
    submit = (event) => {
        console.log(this.state);
        console.log(JSON.stringify(this.state));
        event.preventDefault()
    }
    // Binding events, data collection
    handleChange = async (e) => {
        let name = e.target.name
        let value = e.target.value
        let type = e.target.type
        if (type == "checkbox") {
            console.log(e.target.checked);
            value = e.target.checked
        }
        if (type == "number") {
            value = parseInt(value)
        }
        // Dynamic variable
        // ES6 calculation attribute name [name]
        this.setState({
            [name]: value
        }, () => {
            console.log(this.state);
        })
    }
    render() {
        return (
            <div>
                <form onSubmit={this.submit}>
                    <label>username:
                        {/* props with value specified on the controlled component will prevent the user from changing the input. If you specify 
                            value´╝îHowever, if the input can still be edited, you may accidentally set value to undefined or null.
                            However, when your value can be updated by setState, it can become editable again
                        */}
                        <input type="text" name="username" onChange={this.handleChange} value={this.state.username} />
                    </label>
                    <hr />
                    <label>age:
                        <input type="number" name="age" onChange={this.handleChange} value={this.state.age} />
                    </label>
                    <hr />
                    <label>single:
                        <input type="checkbox" name="single" onChange={this.handleChange} value={this.state.single} />
                    </label>
                    <hr />
                    <label>desc:
                        <textarea name="desc" cols="30" rows="3" onChange={this.handleChange} value={this.state.desc} />
                    </label>
                    <hr />
                    <label>hobby:
                        <select name="hobby" onChange={this.handleChange} value={this.state.hobby}>
                            <option value="eat">eat</option>
                            <option value="drink">drink</option>
                            <option value="paly">play</option>
                        </select>
                    </label>
                    <hr />
                    <input type="submit" />
                </form>
            </div>
        )
    }
}
ReactDOM.render(<App />, document.querySelector(".app"))

Posted by serbestgezer on Mon, 27 Sep 2021 03:25:03 -0700