MobX-utils 간단 정리

이지헌·2023년 11월 26일
0

React.js / Next.js

목록 보기
1/1
post-thumbnail

fromPromise

  • Promise 를 인자로 받아, 2개의 observable 변수를 리턴
    • Parameter

      • origPromise: Promise
      • oldPromise: Promise
        • 이전에 관측되었던 Promise
        • 넘겨주면 Promise 가 진행되는 동안 pending 되지 않고 이전의 값을 보유
      • promise: Promise
        • 관측될 Promise
    • Return
      - value → 초기 값 / Promise 가 리턴한 값 / Promise 가 Reject 한 값
      - state: “pending” | “fulfilled” | “rejected”

      @observer
      class SearchResults extends React.Component {
        @observable.ref searchResults
      
        componentDidUpdate(nextProps) {
          if (nextProps.query !== this.props.query)
            this.searchResults = fromPromise(
              window.fetch("/search?q=" + nextProps.query),
              // by passing, we won't render a pending state if we had a successful search query before
              // rather, we will keep showing the previous search results, until the new promise resolves (or rejects)
              this.searchResults
            )
        }
      
        render() {
          return this.searchResults.case({
             pending: (staleValue) => {
               return staleValue || "searching" // <- value might set to previous results while the promise is still pending
             },
             fulfilled: (value) => {
               return value // the fresh results
             },
             rejected: (error) => {
               return "Oops: " + error
             }
          })
        }
      }
      
      // Observable promises can be created immediately in a certain state using
      // `fromPromise.reject(reason)` or `fromPromise.resolve(value?)`.
      // The main advantage of `fromPromise.resolve(value)` over `fromPromise(Promise.resolve(value))` is that the first _synchronously_ starts in the desired state.
      
      // It is possible to directly create a promise using a resolve, reject function:
      // `fromPromise((resolve, reject) => setTimeout(() => resolve(true), 1000))`

isPromiseBasedObservable

  • 인자로 받은 Observable이 Promise 기반의 Observable 인지 반환
    • Parameter
      • value: observable
    • Return
      • boolean

moveItem

  • Observable Array 와 두 개의 인덱스를 받아 인덱스가 유효한지 검사 후 서로 위치를 변경
    • Parameter

      • target: ObservableArray
      • fromIndex: number
      • toIndex: number
    • Return
      - ObservableArray

      const source = observable([1, 2, 3])
      moveItem(source, 0, 1)
      console.log(source.map(x => x)) // [2, 1, 3]

lazyObservable

  • observable 을 리턴하는 fetch 함수와 초기값을 인자로 받아 최초 사용되는 시점에서 lazy initialization
  • current() 를 호출 했을 때 fetch 가 실행됨
  • refresh() 로 리프레쉬 가능한 듯
    • Parameter

      • fetch: (sink) ⇒ void
      • initialValue
      const userProfile = lazyObservable(
        sink => fetch("/myprofile").then(profile => sink(profile))
      )
      
      // use the userProfile in a React component:
      const Profile = observer(({ userProfile }) =>
        userProfile.current() === undefined
        ? <div>Loading user profile...</div>
        : <div>{userProfile.current().displayName}</div>
      )
      
      // triggers refresh the userProfile
      userProfile.refresh()

fromResource

  • 구독 가능한 외부 데이터 소스와 싱크를 맞춰주는 observable 을 생성
  • current() 를 호출 했을 때 추적 시작
    • Parameter
      - subscriber
      - unsubscriber: IDisposer
      - initialValue: T

      function createObservableUser(dbUserRecord) {
        let currentSubscription;
        return fromResource(
          (sink) => {
            // sink the current state
            sink(dbUserRecord.fields)
            // subscribe to the record, invoke the sink callback whenever new data arrives
            currentSubscription = dbUserRecord.onUpdated(() => {
              sink(dbUserRecord.fields)
            })
          },
          () => {
            // the user observable is not in use at the moment, unsubscribe (for now)
            dbUserRecord.unsubscribe(currentSubscription)
          }
        )
      }
      
      // usage:
      const myUserObservable = createObservableUser(myDatabaseConnector.query("name = 'Michel'"))
      
      // use the observable in autorun
      autorun(() => {
        // printed everytime the database updates its records
        console.log(myUserObservable.current().displayName)
      })
      
      // ... or a component
      const userComponent = observer(({ user }) =>
        <div>{user.current().displayName}</div>
      )

toStream

  • 식을 observable stream (TC 39 Observable / RxJS Observable) 으로 변환
    • Parameter
      - expression
      - fireImmediately: boolean

      const user = observable({
        firstName: "C.S",
        lastName: "Lewis"
      })
      
      Rx.Observable
        .from(mobxUtils.toStream(() => user.firstname + user.lastName))
        .scan(nameChanges => nameChanges + 1, 0)
        .subscribe(nameChanges => console.log("Changed name ", nameChanges, "times"))

createViewModel

  • observable 프로퍼티를 가진 오브젝트를 인자로 받아 뷰 모델로 래핑
  • 뷰 모델의 특성
    • 뷰 모델 프로퍼티에 새로운 값이 할당되지 않으면 이전 프로퍼티의 값 반환
    • 모델에서 값이 변경되면 변경

0개의 댓글