As it were made, whether these things and Flux! That we will see to that. (Some arrangements are being and I think.)
Until vague "Hmm, I see .." Flux you did not somehow only understood in like a feeling actually is realized that was a super-revolutionary paradigm shift has received quite the shock.
By the way, I think in the programming of context and he either Event or Exception to have come up first how much e, in this case it is of course that of the Event is.
The Flux
Flux is I think people there that you have seen so figure that is referenced as you may say always many in the description of, it is that of such architecture.Points ReactViews, ActionCreators, Dispatcher, the arrow of a circle formed from the Store is not only flows in one direction.
Detailed description is I should Kurere read the official site, but personally Dispatcher, View might Madashimo ActionCreator, the impression that the term Store had inhibited the understanding is it does not come isnt focus.
If you replace in your own words ActionCreator, Store are both Model. And, Dispatcher is what the singleton of EventEmitter.
We will look at whether in fact become what implemented in this way of thinking.
EventService
The following is the complete source of EventService of prototype.Since it uses the WebPack, but uses the node.js Ppoku module.exports, contents are together, even if you write as JS of normal client-side.
event.service.js
var EventEmitter = require ("wolfy87-eventemitter");
function EventService () {
this. on ("error", function (source, data) {
. console log ("!!! error !!!", source, data);
});
}
. EventService prototype = new EventEmitter ();
EventService. Prototype. Error = function (source, data) {
. this emit ("error", source, data);
};
. module exports = new EventService ();
event.constant.js
module. exports = {
USER_SIGNIN: "user.signin",
USER_FAIL_SIGNIN: "user.failSignin",
USER_SIGNOUT: "user.signout",
ERROR: "error"
};
We have added the error method for debugging as SyntaxSugar, but substantially EventEmitter is as it is. And what if "var EventService = new EventEmitter ()" We do not matter only one line.
This guy will aggregate all events in the application as a singleton of Dispatcher. Since the literal event name is used dispersed in various places is not cool, event names are aggregated to a constant class.
API
Excerpt Subsequently API
api.js
var $ = require ("jquery");
function API () {
. this endpoint = "";
}
API. Prototype. Exec = function (method, path, data) {
return $. ajax ({
url:. this endpoint + path,
type: method,
data: data
});
};
API. Prototype. Signin = function (nameOrEmail, password) {
return this. exec ("POST", "/ api / auth / signin", {
nameOrEmail: nameOrEmail,
password: password
});
};
API. Prototype. Signout = function () {
. return this exec ("GET", "/ api / auth / signout");
};
. module exports = new API ();
Point is not to pinch the extra processing at all, earnestly that you are devoted to be Sutras the API provided by the server. (Common error process might be added later.) What to do in response to the result of the execution of the API, that part is the role of the Model or the View.
By the way endpoint is usually as an empty, but communicates with the Origin server that generated the content, it will be able to carry out the front-end development without a server Simply slide the URL by preparing a development server that supports CORS. (That we put in the prospectus, but in fact it has not tried yet. Perhaps webpack-dev-server You thought that it might not you use, but its story is also them how much work out.)
Model
Signin as an example, it shows a simplified version of the UserService to process signout.
user.service.js
var $ = require ("jquery");
var api = require ("../api/API");
var EventService = require ("./event.service");
var Events = require ("../constants/event.constants");
function UserService () {
var user;
function getAuthorizedUser () {
return user;
}
function setAuthorizedUser (v) {
user = v;
}
function signin (nameOrEmail, password) {
api. signin (nameOrEmail, password). done (function (data) {
if (data. code == 200) {
. user = data user;
. EventService emit (.. Events SIGNIN, data user);
} Else {
. EventService emit (. Events FAIL_SIGNIN);
}
}). Fail (function (xhr) {
. EventService error ("UserService.signin", xhr);
});
}
function signout () {
if (user) {
api. signout (). done (function (data) {
user = null;
. EventService emit (. Events SIGNOUT);
}). Fail (function (xhr) {
. EventService error ("UserService.signout", xhr);
});
}
}
$. Extend (this, {
getAuthorizedUser: getAuthorizedUser,
setAuthorizedUser: setAuthorizedUser,
signin: signin,
signout: signout
});
}
. module exports = new UserService ();
getAuthorizedUser is a method that returns the user who is logged in.
setAuthorizedUser If put the first load (or reload) at the time already logged in user of HTML, it is the method used to set it.
Signin / signout can run the API, you have to ignite after events that set the user in response to the results.
Point is that these Action methods nothing returns as the return value.
In you are and signin method accustomed to the design of synchronous API will want to return the User object, but it is impossible in the asynchronous processing.
So here returns a Promise. . . Is processed and begin spear will become unnecessarily complicated.
So, you do not have the return value simply by firing the events in these Action methods.
In other words, the caller but can not know whether he had succeeded in actually signin despite calling the UserService # signin, this graciousness is the largest liver of Flux design.
you can watch a separate signin events in EventService If you want to know the results of the signin.
(In this way because the process at the time of fail is always going to be the same when you organize this is still looks good is better to have a common treatment in the API side.)
So, you do not have the return value simply by firing the events in these Action methods.
In other words, the caller but can not know whether he had succeeded in actually signin despite calling the UserService # signin, this graciousness is the largest liver of Flux design.
you can watch a separate signin events in EventService If you want to know the results of the signin.
(In this way because the process at the time of fail is always going to be the same when you organize this is still looks good is better to have a common treatment in the API side.)
View
First, it will show the user component that controls the user's signin / signout.This component is an image that is as user icon of the drop-down form in the top-right corner of the screen Qiita and GitHub, but here for the sake of simplicity.
- Show user name and signout button if already signin
- and display a link to the signin screen if you have not signin
user.component.jsx
var React = require ("react");
. var Navigation = require ('react-router') Navigation;
. var Link = require ('react-router') Link;
var UserService = require ("../models/user.service");
var EventService = require ("../models/event.service");
var Events = require ("../constants/event.constant");
module. exports = React. createClass ({
mixins: [Navigation],
getInitialState: function () {
return {
user:. UserService getAuthorizedUser ()
};
},
onSigninOrSignup: function (user) {
this. setState ({
user: user
});
. this transitionTo ("home");
},
onSignout: function () {
this. setState ({
user: null
});
. this transitionTo ("home");
},
signout: function () {
. UserService signout ();
},
componentDidMount: function () {
. EventService on (.. Events USER_SIGNIN, this onSigninOrSignup);
. EventService on (.. Events USER_SIGNUP, this onSigninOrSignup);
. EventService on (.. Events USER_SIGNOUT, this onSignout);
},
componentWillUnmount: function () {
. EventService off (.. Events USER_SIGNIN, this onSigninOrSignup);
. EventService off (.. Events USER_SIGNUP, this onSigninOrSignup);
. EventService off (.. Events USER_SIGNOUT, this onSignout);
},
render: function () {
.. var user = this state user;
if (user) {
return <div>
<Div> {user. Name} </ div>
<Div> <button onClick = {this. Signout}> MSG. Signout </ button> </ div>
</ Div>
} Else {
return <div> <Link to = "signin"> MSG. signin </ Link> </ div>
}
}
});
You are running UserService # signout by clicking the signout button, but here it does not conduct the switching of the display.
In fact whether you have succeeded in signout than say that you should not change the display in the parting does not know at this stage.
Switching of the display is done in there picking up (the result generated by the call of UserService # signout) signout events.
Signin / signup is not processing this component is done, but we are the switching of the display can be picked up even those events.
Registration / cancellation of various events listener is the theory conducted at componentDidMount / componentWillUnmount.
By the way out from the right course, but MSG is a global object of only defined the key and string. It is possible to switch between Japanese and English by switching the js file referenced in the HTML side.
/i18n/ja/messages.js
var MSG = {
"Signin": "sign-in",
"Signout": "Sign Out",
"Username": "user name",
"Password": "Password",
"Format": function (fmt) {
for (i = 1; i <arguments length;. i ++) {
var reg = new RegExp ("\\ {" + (i - 1) + "\\}", "g")
. fmt = fmt replace (reg, arguments [i]);
}
return fmt;
}
}
signin.component.jsx
var React = require ("react / addons"); var Link = require ('react-router') Link;. var UserService = require ("../models/user.service"); var EventService = require (". ./models/event.service "); var Events = require (" ../constants/event.constant "); var Alert = require (" ./alert.components.jsx ");.. module exports = React createClass ({mixins: [.. React addons LinkedStateMixin], getInitialState: function () {return {nameOrEmail: "", password: "", message: ""};}, signin:. function () {UserService signin (this. ... state nameOrEmail, this state password);}, onFailSignin: function () {this setState ({message: MSG signinFailed..});}, componentDidMount:.. function () {EventService on (Events USER_FAIL_SIGNIN, this. onFailSignin);}, componentWillUnmount: function () {EventService off (Events USER_FAIL_SIGNIN, this onFailSignin);}, render:.... function () {return <div> <h2> {MSG signin} </ h2> <ul > <li> <label> {MSG. usernameOrEmail} </ label> <input type = "text" valueLink = {this. linkState ('nameOrEmail')} /> </ li> <li> <label> {MSG. password} </ label> <input type = "password" valueLink = {this. linkState ('password')} /> </ li> </ ul> <button onClick = {this. signin}> {MSG. signin} </ button> <Alert message = {this state message..}> </ Alert> <hr /> <Link to = "signup"> {MSG signup.} </ Link> </ div>}});
However, failure of signin (such as a password mistake) is there in the event it is necessary to display on this screen will not display the error message is picked up. (Alert is another component that was created because of an error display.)
Thus View components
- Do something in response to user Action
- Do something in response to the events of his interest
Flux rethink
The above is a design pattern that you are going to attempt to use when making the application in the coming React.We will organize that the various modules are doing here again signin as an example.
- Click on the signin button from View
- Run signin action of Model
- Model issued a signin events
And it and is not there is a process flow separately starting from the Event that you are due to Dispatcher "firing of signin events".
- Dispatcher is firing the signin events
- Run the action Model or View correspond
Honest, but during trial and error it does not had a strong awareness of the Flux up there, or this kind of thing and Flux to see what was finished! I was feeling strong because. (Because maybe I ... (^^ ;;; regular document firmly not read I think that detail is also the place where different, but outline it should not be removed.)
Summary
Event-driven is a paradigm that is from a long time ago but, such as Java EventListener Since the instance of the various components is managing the event, there was a portion that is not fully become a loosely coupled eventually.
It is possible to create as a component that was autonomous and independent of the various View Components In this way, for example, "the button the user component of signout also put in another place." The existing components even when there is like a change and impact correction range because there is no I can localize.
Personally, this is fine revolutionary paradigm shift.
If you have thought in comparison with Angular, probably amount of code that must be written better of the React will increase.
Or personally Angular can create how code amount less app even using any means, is thought to be a framework that pursues the proposition that, as a result or is not consistent, "Is there such a do? I also think there is aggressive part of brute force is being used, such as I think. "
One React + Flux will feel that it has become possible to maintain the application simple by rule of the one-way data flow.
Speaking of either when the product has been growing complexity increases, I do it why not overwhelmingly such person of Angular.
If you make such as business systems and services inside for management system of I think more of Angular is facing, but if the consumer app I think Arica even to try using the React.
It does not mention in this article, (such as be replaced at a later time, for example Alert) benefits of component-oriented is also advantageous in making intense consumer application of change.
No comments:
Post a Comment