programing

React with Backbone을 사용할 때 forceUpdate()를 피할 수 있습니까?

easyjava 2023. 3. 10. 22:53
반응형

React with Backbone을 사용할 때 forceUpdate()를 피할 수 있습니까?

Facebook React는 변이체를 분리할 것을 권장합니다(state ) 및 )props★★★★

가능한 한 많은 구성 요소를 상태 비저장 상태로 유지하십시오.이렇게 하면 상태를 가장 논리적인 위치로 격리하고 용장성을 최소화하여 애플리케이션을 쉽게 추론할 수 있습니다.

상태가 변화하면 가상 DOM diff를 트리거하기 위해 를 호출해야 합니다.이 경우 필요한 경우에만 실제 DOM 업데이트가 발생합니다.

호출을 통해 수동으로 DOM 업데이트를 트리거하는 방법이 있지만 권장되지 않습니다.

일반적으로는 의 모든 사용을 피하고 읽기만 해야 합니다.this.props ★★★★★★★★★★★★★★★★★」this.staterender()이것에 의해, 애플리케이션의 심플화와 효율이 향상됩니다.

그러나 내가 본 모든 React+Backbone 예는 이 조언을 무시하고 모델과 컬렉션을 저장합니다.props를 호출합니다.forceUpdate:

에서는 "Resact"를 합니다.forceUpdate:

하지만, 더 나은 방법이 있을까요? 그리고 어떤 이점이 있을까요?

피트의 대답은 훌륭하다.

백본 모델은 본질적으로 변이형입니다.즉, (그 자체는 문제가 되지 않지만) 재렌더할 때 이전 버전의 모델과 비교할 수 없습니다.따라서 컴포넌트의 주요 위치에 메서드를 정의함으로써 인텔리전트 최적화를 실행하는 것이 어려워집니다(또한 실행 취소 의 이유로 이전 버전의 모델을 쉽게 저장할 수 없게 됩니다).

" "forceUpdate 건너뛰다shouldComponentUpdate컴포넌트를 강제로 다시 렌더링합니다.「」를 호출하고 에 주의해 .render는 보통 싸기 는 ", " ", ", "의 이 DOM일 경우에만 합니다.render퍼포먼스 문제가 자주 발생하는 것은 아닙니다.의 데이터 모델 오브젝트 를 사용할 수 있는 모델 속성 오브젝트 )toJSON()피트의 제안대로)를 강력히 추천합니다.

더 나은 답이 나올 때까지, React의 핵심 개발자인 Pete Hunt의 을 인용하겠습니다.

Backbone 모델의 큰 장점은 데이터 흐름을 관리했다는 것입니다.당신이 전화했을 때set()데이터가 변경되었음을 앱에 알립니다.React를 사용하면 콜백을 통해 상태를 소유하는 구성 요소에만 알려주면 되고 React는 모든 자녀가 최신 상태로 유지되도록 하기 때문에 이 작업이 덜 필요함을 알게 됩니다.따라서 백본의 이 부분은 IMO의 유용성이 낮습니다(또한 사람들은 React와 같은 방법으로 백본을 사용하는 경향이 있습니다).

순수 JSON에 합격할 필요는 없지만(단, 단순한 데이터 모델에 적합하지만), 객체를 불변하게 유지하면 많은 이점을 얻을 수 있습니다.

전화만 걸면 시험해 볼 수 있어요.toJSON()백본 모델을 사용하여 원하는 대로 모델을 배포하는 것과 비교합니다.

(내 것을 제외)

흥미롭게도, 백본.Respect.Component는 이 기능을 사용하는 유일한 예입니다.toJSON, 그러나 어떤 이유로든setProps대신setState(이것도 권장되지 않습니다).

갱신하다

Pete Hunt의 접근법에 따라 간단한 믹스인을 만들었습니다.setProps,아니요.forceUpdate):

define(function () {

  'use strict';

  var Backbone = require('backbone'),
      _ = require('underscore');

  var BackboneStateMixin = {
    getInitialState: function () {
      return this.getBackboneState(this.props);
    },

    componentDidMount: function () {
      if (!_.isFunction(this.getBackboneState)) {
        throw new Error('You must provide getBackboneState(props).');
      }

      this._bindBackboneEvents(this.props);
    },

    componentWillReceiveProps: function (newProps) {
      this._unbindBackboneEvents();
      this._bindBackboneEvents(newProps);
    },

    componentWillUnmount: function () {
      this._unbindBackboneEvents();
    },

    _updateBackboneState: function () {
      var state = this.getBackboneState(this.props);
      this.setState(state);
    },

    _bindBackboneEvents: function (props) {
      if (!_.isFunction(this.watchBackboneProps)) {
        return;
      }

      if (this._backboneListener) {
        throw new Error('Listener already exists.');
      }

      if (!props) {
        throw new Error('Passed props are empty');
      }

      var listener = _.extend({}, Backbone.Events),
          listenTo = _.partial(listener.listenTo.bind(listener), _, _, this._updateBackboneState);

      this.watchBackboneProps(props, listenTo);
      this._backboneListener = listener;
    },

    _unbindBackboneEvents: function () {
      if (!_.isFunction(this.watchBackboneProps)) {
        return;
      }

      if (!this._backboneListener) {
        throw new Error('Listener does not exist.');
      }

      this._backboneListener.stopListening();
      delete this._backboneListener;
    }
  };

  return BackboneStateMixin;

});

어떤 모델이나 컬렉션을 가지고 있는지는 신경 쓰지 않습니다.

Backbone 모델이 도입되고 JSON이 믹스인에 의해 자동으로 에 삽입되는 것이 관례입니다.덮어쓸 필요가 있습니다.getBackboneState(props)이 기능이 작동하도록 하기 위해, 그리고 옵션으로watchBackboneProps믹스인에게 언제 전화를 걸어야 할지 알리다setState참신한 가치관을 가지고.

사용 예:

var InfoWidget = React.createClass({
  mixins: [BackboneStateMixin, PopoverMixin],

  propTypes: {
    stampModel: React.PropTypes.instanceOf(Stamp).isRequired
  },

  // Override getBackboneState to tell the mixin
  // HOW to transform Backbone props into JSON state

  getBackboneState: function (props) {
    var stampModel = props.stampModel,
        primaryZineModel = stampModel.getPrimaryZine();

    return {
      stamp: stampModel.toJSON(),
      toggleIsLiked: stampModel.toggleIsLiked.bind(stampModel),
      primaryZine: primaryZineModel && primaryZineModel.toJSON()
    };
  },

  // Optionally override watchBackboneProps to tell the mixin
  // WHEN to transform Backbone props into JSON state

  watchBackboneProps: function (props, listenTo) {
    listenTo(props.stampModel, 'change:unauth_like_count change:is_liked');
    listenTo(props.stampModel.get('zines'), 'all');
  },

  render: function () {
    // You can use vanilla JSON values of this.state.stamp,
    // this.state.toggleIsLiked and this.state.primaryZine
    // or whatever you return from getBackboneState
    // without worrying they may point to old values
  }
}

주의: mixin에는 Underscore 1.6.0+가 필요합니다.

저는 Backbone의 개발자입니다.리액트 컴포넌트setProps를 사용하는 이유는 컴포넌트 소유자(최고 부모)만이 호출하도록 되어 있기 때문입니다.제가 보기에 소품은 상태보다 사후 대응적인 업데이트(및 하위 컴포넌트 전달)에 사용하는 것이 더 낫습니다. 하지만 상태가 더 나은 이유를 알려주시면 기꺼이 그 변화를 위해 개발을 시작할 수 있을 것 같습니다.

예를 들어 transferPropsTo가 매우 편리한 다른 사람에게 위임하는 컴포넌트가 있습니다.국가를 이용하는 것은 그것을 성취하는 것을 더 어렵게 만든다.

언급URL : https://stackoverflow.com/questions/21709905/can-i-avoid-forceupdate-when-using-react-with-backbone

반응형