React between Components _react

Source: Internet
Author: User
There are a lot of questions about how the react components communicate with each other in the group today. The following is a good English version of the translation I saw, people who have read my blog know that my translation may not be step-by-step, will be as far as possible in Chinese meaning, to the author to describe the technology described clearly. English ability is limited, if have the wrong place please with me to leave a message, certain change ... ^_^ original order

The way the communication between the react components is handled depends largely on the relationship between the components, but the relationship is yours.

I don't talk too much about Data-stores, data-adapters or data-helpers. I only focus on the presentation of the react component itself.

The ways in which react components are communicated can be grouped into the following 3 categories:

The parent component passes values to the subassembly;

Sub-component to the parent component values;

Values are passed between components that do not have any nested relationships (PS: For example: Brother between components) one, "parent component" to "sub-component" Pass value

Preliminary use

This is fairly easy to use in the process of using react development, mainly using props to communicate. Examples are as follows:

Parent component
var MyContainer = React.createclass ({
  getinitialstate:function () {return
    {
      checked:true
    }
  ,
  render:function () {return
    (
      <togglebutton text= "Toggle Me" checked={this.state.checked}/ >
    );
  }
);

Sub
-component var ToggleButton = React.createclass ({
  render:function () {
    //value obtained from parent component
    var checked = this. props.checked,
        text = This.props.text;

    Return (
        <label>{text}: <input type= "checkbox" checked={checked}/></label>
    );
  }
);

Further discussion

If the component nesting level is too deep, then the exchange cost of the component from outside to inside becomes very high, the advantage of passing the value through props is less obvious. PS: So I suggest minimizing the level of components, just like writing HTML, simple and clear structures are more attractive.

Parent component
var MyContainer = React.createclass ({
  render:function () {return
    (
      <intermediate text=) Where is my son? "/>
    );
  }

"; Subassembly 1: Intermediate nested component
var intermediate = react.createclass ({
  render:function () {return
    (
      <child text= {this.props.text}/>
    );
  }
)

; Subassembly 2: subcomponent of child component 1
= React.createclass ({
  render:function () {return
    (
      <span>{) This.props.text}</span>
    );
  }
);
Second, "sub-component" to "parent component" transfer value

Next, we introduce "subcomponents" to control their state and then tell the "parent component" the click Status and then show it in the parent component. So we add a change event to do the interaction.

Parent component var MyContainer = React.createclass ({getinitialstate:function () {return {checked:false};
  }, Onchildchanged:function (newstate) {this.setstate ({checked:newstate}); }, Render:function () {var ischecked = this.state.checked?
    ' Yes ': ' No '; Return (<div> <div>are checked: {ischecked}</div> <togglebutton text= "Togg
      Le Me "initialchecked={this.state.checked} callbackparent={this.onchildchanged}/>
  </div>);

}
}); Sub-component var ToggleButton = React.createclass ({getinitialstate:function () {return {Checked:this.props.init
  Ialchecked};
    }, Ontextchange:function () {var newstate =!this.state.checked;
    This.setstate ({checked:newstate});
  Note here: SetState is an asynchronous method, so you need to manipulate the current value of the cache this.props.callbackParent (newstate); The value of Render:function () {//) obtained from the parent component is var text = This.props.Text

    Component's own state data var checked = this.state.checked; Return (<label>{text}: <input type= "checkbox" checked={checked} Onchange={this.ontextcha
  Nge}/></label>);
 }
});

I think the original author of the code is not very intuitive, and then I talk about a flow to the diagram to visually describe the process:

This is actually dependent on props to pass the reference to the event, and it is implemented in a callback way, which is not particularly good, but is a simple implementation without any tools

Here's a question we discussed earlier, that is, when the component has multiple layers nested, you have to pass in a callback function to the props to implement the child component's values or operations to the parent component. Tiny-tip:react Event System

In OnChange events or other react events, you can get the following things:

"This": points to your component

"One parameter": This parameter is a react synthesis event, syntheticevent.

React the management of all events is to achieve their own, and we used before the onclick, onchange events are not the same. Fundamentally, they are all tied to the body.

Document.on (' Change ', ' input[data-reactid= '. 0.2 '] ', function () {...});

The above code doesn't come from react, it's just a metaphor.

If I'm not mistaken, react really handles an event with the following code:

var listento = Reactbrowsereventemitter.listento;
...
function Putlistener (ID, registrationname, Listener, transaction) {
  ...
  var container = Reactmount.findreactcontainerforid (ID);
  if (container) {
    var doc = Container.nodetype = = Element_node_type? container.ownerDocument:container;
    Listento (Registrationname, doc);
  }
  ...
}
Within the listening event, we can find the following:
Target.addeventlistener (EventType, callback, false);

Here are all the events supported by react: Chinese document-Event System

case where multiple subassemblies use the same callback

Parent component var MyContainer = React.createclass ({getinitialstate:function () {return {totalchecked:0};
    }, Onchildchanged:function (newstate) {var newtoral = this.state.totalChecked + (newstate? 1:-1);
  This.setstate ({totalchecked:newtoral});
    }, Render:function () {var totalchecked = this.state.totalChecked; Return (<div> <div>how Many are checked: {totalchecked}</div> <togglebutton te xt= "Toggle Me" initialchecked={this.state.checked} callbackparent={this.onchildchanged}/&gt
        ; <togglebutton text= "Toggle Me Too" initialchecked={this.state.checked} callbackparent={this.onc
          hildchanged}/> <togglebutton text= "and Me" initialchecked={this.state.checked}
  callbackparent={this.onchildchanged}/> </div>);

}
}); Sub-component var ToggleButton = React.createclass ({getinitialstate:function () {return {checked:this.props.initialChecked};
    }, Ontextchange:function () {var newstate =!this.state.checked;
    This.setstate ({checked:newstate});
  Note here: SetState is an asynchronous method, so you need to manipulate the current value of the cache this.props.callbackParent (newstate);
    The value of Render:function () {//) obtained from the parent component is var text = This.props.text;

    Component's own state data var checked = this.state.checked; Return (<label>{text}: <input type= "checkbox" checked={checked} Onchange={this.ontextchange}/></l
  abel>);
 }
});

It is very easy to understand that in the parent component we added a "totalchecked" to replace the "checked" in the previous example, and when the subassembly changes, the parent component is returned a value using the callback function of the same subassembly. Third, values are passed between components that do not have any nested relationships

If there is no relationship between components, the component nesting level is deep (personally think that the 2 level is already deep), or you for some components can subscribe to, write some signals, do not want to insert a component between components, so that two components in a separate relationship. For event systems, here are 2 basic steps: Subscribe (subscribe)/monitor (listen) an event notification and send (send)/trigger (trigger)/publish (publish)/Send (Dispatch) an event to notify those desired components.

Here are 3 ways to handle events, and you can click here to compare them.

Briefly summarize:

(1) Event Emitter/target/dispatcher

Feature: Requires a specified feed

To subscribe
otherobject.addeventlistener (' click ', function () {alert (' click! ');});
To dispatch
this.dispatchevent (' click ');

(2) Publish/subscribe

Feature: When triggering an event, you do not need to specify a particular source because it uses a global object to handle the event (in fact, it is a global
Broadcast way to handle events)

To subscribe
globalbroadcaster.subscribe (' click ', function () {alert (' click! ');});
To dispatch
globalbroadcaster.publish (' click ');

(3) Signals

Features: Similar to event emitter/target/dispatcher, but you should not use random strings as triggers for events. Each object that triggers an event needs an exact name (the name of the write event that is similar to the Hard-coded Class), and the exact event must be specified when the trigger is triggered. (see example, very good understanding)

To subscribe
otherObject.clicked.add (function () {alert (' click ');});
To dispatch
This.clicked.dispatch ();

If you just want to use it simply, you don't need to do anything else, you can do it in a simple way:

Simple implementation of the subscribe and dispatch
var eventemitter = {
    _events: {},
    dispatch:function (event, data) {
        if (!) This._events[event]) {//No listener event return
          ;
        }
        for (var i = 0; i < this._events[event].length i++) {
            this._events[event][i] (data);
        }
    ,
    subscribe : Function (event, callback) {
      //Create a new event array
      if (!this._events[event]) {
        this._events[event] = [];
      }
      This._events[event].push (callback);
    }
;

Otherobject.subscribe (' namechanged ', function (data) {alert (data.name);});
This.dispatch (' namechanged ', {name: ' John '});

If you want to use the Publish/subscribe model, you can use: PUBSUBJS

The REACT team uses the following: Js-signals it is based on signals mode and is pretty good to use. Events in react

When using the React event, you must focus on the following two methods:

Componentdidmount
Componentwillunmount

When dealing with events, you need to be aware of:

In the Componentdidmount event, if the component mount (mounted) completes, subscribes to the event, and when the component unloads (unmounted), cancels the subscription to the event in the Componentwillunmount event.

(if it's not clear that you can refer to react's documentation for the lifecycle, there are also descriptions.) In the original article is Componentwillmount personally think that should be mounted after the completion of subscription events, such as animation This must be mounted, and can not be dynamically added, cautious point better)

Because the rendering and destruction of components is controlled by react, we do not know how to reference them, so the Eventemitter mode is not very useful in processing components.

Pub/sub mode can be used, you do not need to know references.

Here's an example: the implementation has multiple product components, and clicking on them shows the name of the product.

(I introduced the previous recommended PUBSUBJS library in the example, if you think the introduction price is too big, also can write a simple version, or easier, very good ah, you can also experience, but I still do not recommend the way of global Broadcasting)

Defines a container var productlist = React.createclass ({render:function () {return) (<div> ;
          Productselection/> <product name= "Product 1"/> <product "Product 2" name=
    <product name= "Product 3"/> </div>);
}
}); Product information for display click the container var productselection = React.createclass ({getinitialstate:function () {return {selection:
  ' None '};
      }, Componentdidmount:function () {This.pubsub_token = Pubsub.subscribe (' Products ', function (topic, product) {
    This.setstate ({selection:product});
  }.bind (this));
  }, Componentwillunmount:function () {pubsub.unsubscribe (This.pubsub_token);
    }, Render:function () {return (<p>you have selected the product: {this.state.selection}</p>
  );

}
});
  var Product = React.createclass ({onclick:function () {pubsub.publish (' products ', this.props.name); }, RendeR:function () {return <div onclick={this.onclick}>{this.props.name}</div>;
 }
});

Es6:yield and JS-CSP

There is a way to pass information in ES6, using the Build function (generators) and the yield keyword. Can take a look at HTTPS://GITHUB.COM/UBOLONTON/JS-CSP

(Here I write a simple DEMO to introduce this new way of delivery, in fact, similar)

function* list () {for
    (var i = 0; i < arguments.length; i++) {
        yield arguments[i];
    }
    Return to "done.";
}

var o = list (1, 2, 3);

var cur = o.next;
while (!cur.done) {
    cur = o.next ();
    Console.log (cur);
}

The above example comes from a blog from Cucques: Introduction to the generator function in ES6 Cucques is a Daniel, you can always pay attention to his blog.

Generally, you have a queue in which the object can find a reference, lock it when it is defined, and immediately open the lock execution when it occurs. JS-CSP is a solution, and perhaps there will be other solutions later. End

In practical application, according to the actual need to solve the need to choose a solution. For small applications, you can use the props and callback methods to exchange data between components. You can go through the pub/sub mode to avoid polluting your components. Here, we are not talking about data, just components. For data requests, data changes and other scenarios, you can use the Facebook Flux, Relay, graphql to deal with, are very useful.

Each of the examples I have verified, mainly using the most original way to introduce files, the creation of services using the Http-server package, you can also try to do it yourself.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.