在Facebook React中使用Mixins与组件进行代码重用

在Facebook React中使用Mixins与组件进行代码重用,第1张

在Facebook React中使用Mixins与组件进行代码重用

更新:这个答案已经过时了。如果可以的话,请远离mixin。我警告过你!
Mixins已死。 万岁组成

首先,我尝试为此使用子组件并提取

FormWidget
InputWidget
。但是,我中途放弃了这种方法,因为我想更好地控制生成的
input
s及其状态。

有两篇对我最有帮助的文章:

  • 在React中思考使我意识到我实际上并不需要嵌套组件。
  • 可重用组件有一个简洁的混合示例。

事实证明,我只需要编写两个(不同的)mixin:

ValidationMixin
FormMixin

这是我分开它们的方式。

验证Mixin

验证mixin添加了方便的方法,可以在状态的某些属性上运行验证器函数,并将“错误的”属性存储在

state.errors
数组中,以便突出显示相应的字段。

来源(要点)
define(function () {  'use strict';  var _ = require('underscore');  var ValidationMixin = {    getInitialState: function () {      return {        errors: []      };    },    componentWillMount: function () {      this.assertValidatorsDefined();    },    assertValidatorsDefined: function () {      if (!this.validators) {        throw new Error('ValidatorMixin requires this.validators to be defined on the component.');      }      _.each(_.keys(this.validators), function (key) {        var validator = this.validators[key];        if (!_.has(this.state, key)) {          throw new Error('Key "' + key + '" is defined in this.validators but not present in initial state.');        }        if (!_.isFunction(validator)) {          throw new Error('Validator for key "' + key + '" is not a function.');        }      }, this);    },    hasError: function (key) {      return _.contains(this.state.errors, key);    },    resetError: function (key) {      this.setState({        'errors': _.without(this.state.errors, key)      });    },    validate: function () {      var errors = _.filter(_.keys(this.validators), function (key) {        var validator = this.validators[key], value = this.state[key];        return !validator(value);      }, this);      this.setState({        'errors': errors      });      return _.isEmpty(errors);    }  };  return ValidationMixin;});
用法

ValidationMixin
有三种方法:
validate
hasError
resetError

它期望类定义
validators
对象,类似于
propTypes

var JoinWidget = React.createClass({  mixins: [React.addons.linkedStateMixin, ValidationMixin, FormMixin],  validators: {    email: Misc.isValidEmail,    name: function (name) {      return name.length > 0;    }  },  // ...});

当用户按下提交按钮时,我致电

validate
。调用
validate
将运行每个验证器,并填充
this.state.errors
一个数组,该数组包含验证失败的属性的键。

在我的

render
方法中,我用来
hasError
为字段生成正确的CSS类。当用户将焦点放在该字段内时,我会调用
resetError
以删除错误突出显示,直到下一次
validate
调用为止。

renderInput: function (key, options) {  var classSet = {    'Form-control': true,    'Form-control--error': this.hasError(key)  };  return (    <input key={key}type={options.type}placeholder={options.placeholder}className={React.addons.classSet(classSet)}valuelink={this.linkState(key)}onFocus={_.partial(this.resetError, key)} />  );}
FormMixin

表单混合处理表单状态(可编辑,提交,已提交)。您可以使用它在发送请求时禁用输入和按钮,并在发送请求时相应地更新视图。

来源(要点)
define(function () {  'use strict';  var _ = require('underscore');  var EDITABLE_STATE = 'editable',      SUBMITTING_STATE = 'submitting',      SUBMITTED_STATE = 'submitted';  var FormMixin = {    getInitialState: function () {      return {        formState: EDITABLE_STATE      };    },    componentDidMount: function () {      if (!_.isFunction(this.sendRequest)) {        throw new Error('To use FormMixin, you must implement sendRequest.');      }    },    getFormState: function () {      return this.state.formState;    },    setFormState: function (formState) {      this.setState({        formState: formState      });    },    getFormError: function () {      return this.state.formError;    },    setFormError: function (formError) {      this.setState({        formError: formError      });    },    isFormEditable: function () {      return this.getFormState() === EDITABLE_STATE;    },    isFormSubmitting: function () {      return this.getFormState() === SUBMITTING_STATE;    },    isFormSubmitted: function () {      return this.getFormState() === SUBMITTED_STATE;    },    submitForm: function () {      if (!this.isFormEditable()) {        throw new Error('Form can only be submitted when in editable state.');      }      this.setFormState(SUBMITTING_STATE);      this.setFormError(undefined);      this.sendRequest()        .bind(this)        .then(function () {          this.setFormState(SUBMITTED_STATE);        })        .catch(function (err) {          this.setFormState(EDITABLE_STATE);          this.setFormError(err);        })        .done();    }  };  return FormMixin;});
用法

它期望组件提供一种方法:

sendRequest
,该方法应返回Bluebird
Promise。(修改它以与Q或其他Promise库一起使用是微不足道的。)

它提供了便利的方法,例如

isFormEditable
isFormSubmitting
isFormSubmitted
。它还提供了启动请求的方法:
submitForm
。您可以从表单按钮的
onClick
处理程序中调用它。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5622579.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存