Skip to content

Instantly share code, notes, and snippets.

@littlehaker
Last active September 6, 2015 15:53
Show Gist options
  • Save littlehaker/7f51020abc19a750f09a to your computer and use it in GitHub Desktop.
Save littlehaker/7f51020abc19a750f09a to your computer and use it in GitHub Desktop.
FRP + React + Async validate
var React = require('react');
var $ = require('jquery');
var h = require('react-hyperscript');
var R = require('ramda');
var V = require('promise-validate');
var Bacon = require('baconjs');
var validateUsername = V.pipe(V.isEmail('请输入邮箱'), V.isLength('最短4个字符,最长10个字符', 4, 10));
var validateUsername$ = function(val) {
return Bacon.fromPromise(validateUsername(val));
};
var App = React.createClass({
getInitialState: function() {
return {
username: null,
username_error: null,
errors: {}
};
},
componentWillMount: function() {
this.submit$ = new Bacon.Bus();
var username$ = this.submit$.map(function() {
return $(React.findDOMNode(this.refs.username)).val();
}.bind(this)).flatMap(validateUsername$).log();
var username_valid$ = username$.map(true).mapError(false);
this.state$ = Bacon.combineWith(
function(username, error, is_valid) {
return {
username: username,
errors: {
username: is_valid ? null : error
}
};
},
username$.skipErrors().toProperty(''),
username$.errors().mapError('.message').toProperty(null),
username_valid$
).log();
this.state$.onValue(function(state) {
this.setState(state);
}.bind(this));
},
connectHandlerStream: function(stream$) {
return function(e) {
stream$.push(e);
}.bind(this);
},
render: function() {
return h('div', [
h('label', '帐号'),
h('input', {ref: 'username'}),
h('span', this.state.errors.username),
h('br'),
h('label', '密码'),
h('input', {ref: 'password'}),
h('br'),
h('button', {onClick: this.connectHandlerStream(this.submit$)}, '提交')
]);
}
});
React.render(h(App), document.getElementById('container'));
var React = require('react');
var $ = require('jquery');
var h = require('react-hyperscript');
var V = require('promise-validate');
var Bacon = require('baconjs');
var validateUsername = V.pipe(V.isEmail('请输入邮箱'), V.isLength('最短4个字符,最长10个字符', 4, 10));
var validateUsername$ = function(val) {
return Bacon.fromPromise(validateUsername(val));
};
var App = React.createClass({
connect: function(stream$, key) {
stream$.onValue(function(val) {
var state = {};
state[key] = val;
this.setState(state);
}.bind(this));
},
connectError: function(stream$, key) {
stream$.onError(function(error) {
var state = {};
state[key] = error.message;
this.setState(state);
}.bind(this));
stream$.onValue(function() {
var state = {};
state[key] = null;
this.setState(state);
}.bind(this));
},
connectHandlerStream: function(stream$) {
return function(e) {
stream$.push(e);
}.bind(this);
},
getInitialState: function() {
return {
username: null,
username_error: null
};
},
componentWillMount: function() {
this.submit$ = new Bacon.Bus();
var username$ = this.submit$.map(function() {
return $(React.findDOMNode(this.refs.username)).val();
}.bind(this)).flatMap(validateUsername$).log();
this.connect(username$, 'username');
this.connectError(username$, 'username_error');
var password$ = this.submit$.map(function() {
return $(React.findDOMNode(this.refs.password)).val();
}.bind(this)).log();
},
render: function() {
return h('div', [
h('label', '帐号'),
h('input', {
ref: 'username'
}),
h('span', this.state.username_error),
h('br'),
h('label', '密码'),
h('input', {
ref: 'password'
}),
h('br'),
h('button', {
onClick: this.connectHandlerStream(this.submit$)
}, '提交')
]);
}
});
React.render(h(App), document.getElementById('container'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment