The state of reactjs in es6 grammar and the practice of props transfer between components

Posted by Kilgore Trout on Sat, 22 Jun 2019 00:01:06 +0200

PS: The first piece of nonsense

It's a little comforting to remember that a month ago I didn't know how reactjs should be started, but it's a little scary to look back at some of the pits and the startups. Today, I would like to share some of my practical carefulness with new friends.

es6 grammatical form of reactjs

Needless to say more about the others, just two points:

  • constructor and super

  • this.functionName=this.functionName.bind(this)

constructor(props) and super(props) generally either do not appear or appear at the same time, meaning is actually inheritance, these two things are not reactjs, but es6, the former is a general constructor, equivalent to es5 inside.

function FunctionName(props) {
    this.props=props;
}

super(props) inherits the attributes of the parent class (meaning function Son (name) {Parent. call (this, name)} in es5) and gets this correctly inside the constructor, which points to the subclass at this time. If you don't write super(props) before you do this (console.log(this)), you will get an error, which probably means that you can't write this before super().

Sometimes it seems no problem to see constructor() and super(), that is, not to write props. Naturally, this.props is not used inside the constructor. In fact, this.state is commonly used inside the constructor. It seems that this.props is not written much.

this.functionName=this.functionName.bind(this) is a binding method to a subclass, so that this is the current subclass (so-called this pointing). You can also write. bind(this) directly where function definitions are, such as onClick={this.handleClick.bind(this)} on render rendered elements.

this.state and this.setState({}) and propsName={stateName}

The role of state in the state rendering of reactjs components is self-evident, which is called state rendering machine. Various attribute values of element nodes and their changes are basically accomplished by the state values and changes provided by state. For example, text changes of elements, value values of forms, checked, disabled and even css styles can be rendered with state. A brief illustration is provided below.

import React,ReactDOM from 'react';
import $ from 'jquery';
class Comp extends React.Component {
    constructor(){
        super();
        this.handleChange=this.handleChange.bind(this);
        this.handleClick=this.handleClick.bind(this);
        this.state={
            value: "",
            msg: ""
        }
    }
    handleChange(e){
        this.setState({
            value: e.target.value
        })
    }
    handleClick(){
        let {value}=this.state;
        $.ajax({
            ...
            data: {
                value:value
            },
            success:(data)=>{
                this.setState({
                    msg: data
                })
            }
        })
    }
    render(){
        let {value,msg}=this.state; 
        return(
            <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <input type="button" value="Submission" onClick={this.handleClick} />
                <span>{msg? msg:"Load here ajax Information returned"}</span>
            </div>
        )
    }
}
ReactDOM.render( <Comp />, document.body)

The above example is rendered on the page with a button, an input box and an information prompt. Because reactjs advocates one-way data flow, when the value state is initially empty, input information cannot be obtained if it is entered directly in the input box without setting the value state. This rendering process is: first, when the page is loaded, it generates the corresponding state according to the three state values in the default this.state. The onChange event constantly changes the value of the state. At this time, the state receives the change and immediately re-renders the value in the input box on the page. That is, whenever any action changes the state value, the page will re-render the corresponding place (about other reactjs entry). Door case demo can refer to my own github).

props attributes and passing

Note that if the props parameter is not passed in the constructor, this.props cannot be used internally. But that doesn't mean that other places like render can't be used internally. At present, it is only realized that the initial source of props passed between components is generally the state value, which may be the cause of insufficient practice.

1. The parent component passes values to the child component

This is a common way of communicating between parent and child components. The attribute value on the child component can be understood as a parameter, but the parent component needs to pass an actual value. Value transfer is generally necessary to reuse components, because there may be multiple pages of the content of a certain part of the highly similar or even the same, at this time only need to pass different values to a component can be used many times. The following examples are given:

Assume that the component files are in the root directory:
//Subcomponent Son.js
class Son extends React.Component{
    render(){
        let {title,userValue,pwdValue,handleChange,handleSubmit}=this.props;
        return(
            <div>
                <h3>{title}</h3>
                <input type="text" value={userValue} onChange={(e)=>handleChange("user",e.target.value} />
                <input type="password" value={pwdValue} onChange={(e)=>handleChange("pwd",e.target.value} />
                <input type="button" value="Submission" onClick={handleSubmit} />
            </div>
        )
    }
}
//Paternal Component 1:Login.js
import Son from './Son.js';
class Login extends React.Component{
    constructor(){
        super();
        this.handleChange=this.handleChange.bind(this);
        this.handleSubmit=this.handleSubmit.bind(this);
        this.state={
            user:{
                value:"",
                error:false
            },
            pwd:{
                value:"",
                error:false
            }
        }
    }
    handleChange(field,val){
        let newState={value:val, error:true};
        switch(field) {
            case "user":
                if (!val.length){
                    newState.error=false
                } else if (val.length>4) {
                    newState.error=false
                }
                this.setState({
                    user:newState
                })
                break;
            case "pwd":
                if (!val.length){
                    newState.error=false;
                } else if (val.length>6) {
                    newState.error=false
                }
                this.setState({
                    pwd:newState
                })
                break;
        }
    }
    handleSubmit() {
        let {user, pwd}=this.state;
        if (!user.error || !pwd.error) {
            alert("Please try again!");
            return;
        } else {
            $.ajax({
                ...
                data: {
                    username: user.value,
                    password: pwd.value
                },
                ...
            })
        }
    render(){
        let {user, pwd}=this.state;
        return(
            <Son title="Please login" userValue={user.value} pwdValue={pwd.value} handleChange={this.handleChange} handleSubmit={this.handleSubmit} />
        )
    }
}

I believe you can see that this is the rudiment of the login page, which is limited to the explanation of the principle, let's not entangle with what the specification is. Generally speaking, since there is login, there is also registration, registration page is basically the same reason. It should be noted that the attribute values and methods on the subcomponents are all this.props. The reason why this.handleChange or this.handleSubmit is not written here is that the subcomponents themselves do not have this method, so if this.xxx is added to the method on the subcomponents at this time, it will be wrong, presumably this method is not a function! Attribute values are similar; at the same time, using unpacking expressions to write this.props indicates that these attributes and methods are inherited from the parent component, so long as the method is defined on the parent component, it is not necessary to write constructor() and super() on the child component at this time.

2. Value transfer from parent component to child component of parent component

This scenario is mainly used when components are more nested. For example, we found that in the sub-component Son.js, there are three input boxes: username and password, but they seem to be a little different. So let's perfect this form:

New Component Form.js
class Form extends React.Component{
    render(){
        let {handleSubmit, userValue, pwdValue, handleChange}=this.props;
        return(
            <form  onSubmit={handleSubmit} method="post" action="/submit">
                <input type="text" name="user" value={userValue} onChange={(e)=>handleChange("user",e.target.value} />
                <input type="password" name="pwd" value={pwdValue} onChange={(e)=>handleChange("pwd",e.target.value} />
                <input type="submit" />
            </form>
        )
    }
}

With this component, the Son.js component for the form can be transformed (also assuming that all components are in the root directory):

//Son.js
import Form from  './Form.js';
class Son extends React.Component{
    render(){
        let {title,userValue,pwdValue,handleChange,handleSubmit}=this.props;
        return(
            <div>
                <h3>{title}</h3>
                <Form 
                    userValue={userValue}
                    pwdValue={pwdValue}
                    handleChange={handleChange}
                    handleSubmit={handleSubmit}
                />
            </div>
        )
    }
}

Maybe novice children's shoes don't quite understand whether the attribute and method names on Son.js components must be the same as those on grandchildren components, because I did struggle to learn this place, but please note that as long as a function (Form.js) is specified after the native method on elements such as onChange or onSubmit, such as onChange={handleChange}, then When the handleChange is passed, the handleChange={handleChange} on the superior component (Son. js) has the method of the superior component on the left, which can be renamed as footChange.... The method handleChange is passed to the lower component on the right, so the right function name of onChange in the lower component Form. JS must correspond to it.

In addition, we can make a simple welcome page based on Son.js:

//Welcome.js
class Welcome extends React.Component{
    render(){
        return(
            <h1>Welcome!</h1>
        )
    }
}
//SonWelcome.js
import Welcome from './Welcome.js';
class SonWelcome extends React.Component{
    render(){
        return(
            <div>
                <h3>{this.props.title}</h3>
                <Welcome />
            </div>
        )
    }
}

Of course, SonWelcom.js is too simple... At the same time, the value of title depends on the value passed by the upper component. Brothers have a big brain hole.

3. How to pass values between non-superior and non-sibling components

It is believed that this situation is relatively rare, but it is worth studying. Some brothers and gods certainly know how to solve it. The so-called sibling component is a multi-component with a common parent component or a "master component", which is similar to the above situation. It can mount the common values needed between sibling components to the higher components. Instead of subordinate and non-sibling components, the application scenario is somewhat similar (note, just similar) to session or cookie, such as multiple pages that need to be rendered differently depending on whether the user is logged in or whether it is an administrator superuser.
First of all, we recommend a js library: PubSubJs, which we can learn more about. (Actually, I haven't used it.) Secondly, tell me what I think. As mentioned above, assuming that this property or method does not involve security issues when rendering components, why not set it to cookie or session? Which component needs this value is presented. Two components are as follows:
For the time being, no matter where the custom flag comes from, at the same time, the style of. activity is: display:none;

//CompOne.js
class CompOne extends React.Component{
    render(){
        return(
            <div>
                <p className={flag? "":"active"}>This first component</p>
            </div>
        )
    }
}
//CompTwo.js
class CompTwo extends React.Component{
    render(){
        return(
            <div>
                <p className={flag? "active":""}>This second component</p>
            </div>
        )
    }
}

Assuming that the above two components are unrelated and have a common custom attribute flag, the two components are hidden or displayed according to the meaning of flag. At this point, a component Cookie can be built to encapsulate a constructor HandleCookie internally, three methods setCookie(name, value, time),getCookie(name),clearCookie(name, value, time). Suppose that name is the cookie name, value is the cookie value, time parameter refers to the length of cookie storage time of the current time, set to 1 to indicate expiration after one day, and set-1 to indicate expiration.

Under this assumption, the above two components can directly take the corresponding value of the cookie flag name when rendering the page and render the page according to the value. For example, set a cookie: {flag:""1"}, CompOne.js:

//CompOne.js
import Cookie from './Cookie.js';
class CompOne extends React.Component{
    render(){
        let flag=Cookie.getCookie("flag");
        return(
            <div>
                <p className={flag? "":"active"}>This first component</p>
            </div>
        )
    }
}

According to this arrangement, the component CompOne will be rendered and displayed, while CompTwo will be hidden. However, this method is obviously not a normative method, just an idea, hope!

Written at the end

If there is something wrong with the above, please correct it and give the younger brother a chance to reform. If children's shoes are also interested in other places that are not thoroughly written, you can refer to one of my own. Message book It's one of the best materials for introducing reactjs, webpack configuration, nodejs and express in China. Star if you feel it's easy to use. Hey, I'm sorry to ask for star.^^

Topics: Javascript React Attribute Session JQuery