programing

Facebook React에서 코드 재사용을 위해 mixins vs components 사용

lastmoon 2023. 3. 28. 22:31
반응형

Facebook React에서 코드 재사용을 위해 mixins vs components 사용

저는 Backbone 프로젝트에서 Facebook React를 사용하기 시작했고, 지금까지는 잘 되어가고 있습니다.
하지만 리액트 코드에 중복이 섞여 있는 것을 알 수 있었습니다.

예를 들어 다음과 같은 상태를 가진 여러 양식 위젯이 있습니다.INITIAL,SENDING ★★★★★★★★★★★★★★★★★」SENT유효성이 상태가 갱신됩니다 버튼을 누르면 폼의 유효성을 확인하고 요청을 한 후 상태를 갱신해야 합니다.는 리액트 에 유지됩니다.this.state★★★★★★★★★★★★★★★★★★★★★★★★★★★

뷰라면, 「Backbone」, 「Base Class」라고 하는 입니다.FormView하지만 내 인상은 React가 뷰 로직을 공유하는 하위 분류를 지지하지도 않는다는 이었다(내가 틀렸다면 정정해 달라).

React에서 코드 재사용을 위한 두 가지 접근 방식을 보았습니다.

React에서 상속하는 것보다 믹스인과 컨테이너를 선호하는 것이 맞습니까?이것은 고의적인 설계 결정입니까?두 번째 단락의 "양식 위젯" 예제에 혼합 또는 용기 구성요소를 사용하는 것이 더 의미가 있습니까?

여기 그들의 현재 상태에 대한 요지가 있다.그들은 비슷한 구조를 가지고 있다.beginSend둘 다 검증 지원이 필요합니다(아직은 필요 없음).

데이: 이이답답답답래래래래오다다다다다.가능하면 믹스인에 접근하지 마세요.★★★★★★★★★★★★★★★★!
믹스인은 죽었다. 작곡

에는 이 하여 이 서브 컴포넌트를 추출하려고 .FormWidget ★★★★★★★★★★★★★★★★★」InputWidget단, 생성된 것을 보다 잘 제어하고 싶었기 때문에 이 접근방식을 중도에 포기했습니다.input아, 아, 아, 아, 아, 아, 아, 아, 아.

가장 큰 도움이 된 기사 두 개:

두 믹스인만 .ValidationMixin ★★★★★★★★★★★★★★★★★」FormMixin.
가가구구 구구구구

검증 믹신

중 'd" 저장하는 합니다.state.errors배열을 지정하여 해당 필드를 강조 표시할 수 있습니다.

소스(gist)

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에는 다음 3가지 방법이 있습니다.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)} />
  );
}

폼믹신

폼 믹스인은 폼 상태(편집 가능, 송신, 송신)를 처리합니다.요청을 보내는 동안 입력 및 버튼을 비활성화하고 요청을 보낼 때 그에 따라 보기를 업데이트할 수 있습니다.

소스(gist)

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블루버드 약속을 돌려줘야지(Q 또는 다른 약속 라이브러리와 연동하도록 수정하는 것은 간단합니다).

다음과 같은 편리한 방법을 제공합니다.isFormEditable,isFormSubmitting그리고.isFormSubmitted또, 요구를 개시하는 방법도 있습니다.submitForm 수 있습니다.onClick핸들러

React로 SPA를 만들고 있는데(1년 전부터 생산) 믹스인은 거의 사용하지 않습니다.

에 대한 React의 방식React)을 을 공유하는 입니다.componentDidMount이 문제는 Dan Abramov가 링크에서 말하는 고차 컴포넌트(또는 ES6 클래스 상속 사용)로 해결됩니다.

또한 혼합은 React의 숨겨진 컨텍스트 기능을 사용하여 프레임워크 API를 모든 구성요소에서 사용할 수 있도록 하기 위해 프레임워크에서 자주 사용됩니다.이는 ES6 클래스 상속에서도 더 이상 필요하지 않습니다.


대부분의 경우 믹스인이 사용되지만 실제로는 필요하지 않으며 간단한 도우미로 대체될 수 있습니다.

예를 들어 다음과 같습니다.

var WithLink = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

리팩터링 할 수 요.LinkedStateMixin을 사용하다

var WithLink = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={LinkState(this,'message')} />;
  }
});

큰 차이가 있나요?

언급URL : https://stackoverflow.com/questions/21854938/using-mixins-vs-components-for-code-reuse-in-facebook-react

반응형