리듀서 없는 상태 관리

연결되지 않은 추상 코드 조각을 연결하는 데 문제가 있고 상태가 업데이트되는 방법과 위치를 이해하는 데 어려움을 겪는 나와 같은 개발자라면. 그러면 인간 두뇌의 제한된 working memory의 한계에 부딪힐 수도 있습니다.

이점을 잃지 않고 감속기를 제거하는 방법, 해결책을 찾은 것 같습니다. 지난 10개월 동안 리듀서를 사용하지 않는 ActiveJS이라는 효율적인 상태 관리자를 구축했습니다.

Instead of dispatching actions and let reducers implicitly work their magic, we just dispatch reducer like pure-functions and get rid of actions in the process; two birds with one stone.



이러한 순수 함수는 현재 상태를 가져와 새 상태를 생성하기 때문에 생산자라고 합니다.

따라서 리듀서가 감소하고 생산자가 생산하지만 기본적으로 상태를 업데이트하는 동일한 작업을 수행합니다. 좋은 것 같죠?

이론을 테스트하고 몇 가지 코드를 작성해 봅시다.

감속기를 사용한 상태 관리



먼저 좋은 오래된 감속기를 살펴 보겠습니다.
이것이 리듀서의 챔피언인 Redux로 구현된 간단한 카운터의 모습입니다.

const counter = (state, action) => {
  if (typeof state === 'undefined') {
    return 0
  }

  // these are our reducers
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

// initialize the store and bind the reducers
const store = Redux.createStore(counter)

// subscribe for the state changes and log it to console
store.subscribe(() => console.log(store.getState()));
// logs 0 immediately and will log any future values

// dispatch the action for increment
store.dispatch({ type: 'INCREMENT' }) // makes the count 1

// dispatch the action for decrement
store.dispatch({ type: 'DECREMENT' }) // makes the count 0

이제 감속기를 생산자로 교체하면 어떤 일이 발생하는지 봅시다.

생산자와 상태 관리



이를 위해 블록의 새로운 아이인 ActiveJS를 사용합니다. 여기에는 Units 이라는 기본 제공 반응형 데이터 구조가 있습니다. 이 구조는 number , string , array 등과 같은 기본 데이터 구조를 값으로 저장하고 제공합니다.

해당 단위 중 하나는 NumUnit 이며 number 값을 저장하고 number 을 유지하도록 합니다. NaN 도 허용되지 않습니다.

카운트가 항상 number 일 것으로 예상하기 때문에 NumUnit을 사용하여 카운터를 구현합니다.

// initialize a reactive data structure to store numbers
const counter = new NumUnit() // with default initial-value 0

// two producers, pure-functions to produce an appropriate new value
const increment = value => value + 1 
const decrement = value => value - 1

// subscribe for reactive value access, and log the value
counter.subscribe(value => console.log(value))
// immediately logs 0, and will log any future values

// dispatch the "increment" producer for increment
counter.dispatch(increment); // you'll see 1 in the console
// the pure function is called with the current value and
// the returned value is dispatched automatically

// dispatch the "decrement" producer for decrement
counter.dispatch(decrement); // you'll see 0 in the console

Look ma, No Reducers!



쉽죠?

페이로드가 있는 작업은 어떻습니까?



현재 값에 페이로드로 제공된 숫자를 곱한 후 현재 값을 증가시키고 싶다고 가정해 보겠습니다. 해당 생산자가 어떻게 생겼는지 봅시다.

const multiplyAndIncrement = multiplier => {
  // the wrapper function acts as an action, and
  // this is our producer now
  return value => value * multiplier + 1
}

// assume the current value of the counter is 2, for easy demonstration

// dispatch the producer
counter.dispatch(multiplyAndIncrement(3))
// the new value becomes 7, because 2 * 3 + 1 is 7

// we call multiplyAndIncrement function and it returns the producer-function
// the dispatch method calls the returned producer with the current value
// the returned value from the producer is used as new value

이론이 확인되고 코드가 여전히 작동하고 쉽게 테스트할 수 있으며 코드 흐름이 중단되지 않습니다.

그러나 프로듀서는 유닛의 좋은 점 중 하나일 뿐이며 많은 기능이 내장되어 있습니다.

다음은 "카운터"와 관련된 기능 중 일부입니다.

직접 파견



생산자를 사용할 필요가 없다면 새 값을 직접 전달할 수 있습니다.

counter.dispatch(2) // works
counter.dispatch(3) // works

직접적인 가치 접근



반응적으로 무언가를 수행하지 않고 값만 필요한 경우 직접 액세스할 수 있습니다.

// static value access
counter.value() // returns the current value immediately

유효하지 않은 데이터 유형 방지



이를 위해 우리는 아무것도 할 필요가 없습니다. NumUnit이 처리합니다.number 만 가져오므로 항상 number 값을 제공합니다. 온전성 검사의 필요성을 줄여줍니다.

counter.dispatch('an evil string') // won't work
counter.dispatch({nein: 'nein nein'}) // won't work
counter.dispatch(NaN) // won't work
counter.dispatch(() => NaN) // won't work
counter.dispatch(['what', 'about', 'this']) // won't work

중복 발송 방지



중복 값을 방지하는 것은 구성 옵션을 제공하는 것만큼 쉽습니다.

const counter = new NumUnit({distinctDispatch: true})
// that's it, done

counter.dispatch(2) // works
counter.dispatch(2) // won't work, it'll get ignored

counter.dispatch(3) // works
counter.dispatch(3) // won't work, it'll get ignored

음수 값 방지



카운터가 양수 값만 가져야 한다는 것은 이치에 맞습니다. 또한 기능을 제공하여 쉽게 확인할 수 있습니다. 새 값을 업데이트해야 하는지 여부를 확인하기 위해 Unit에서 호출합니다.

const counter = new NumUnit({
 // If it returns a falsy value for a dispatch, that dispatch is ignored.
 // So just return true if the newly dispatched value is positive.
  customDistinctDispatch: (prev, newValue) => newValue >= 0
})
// that's it, done

counter.dispatch(2) // works
counter.dispatch(-2) // won't work, it'll get ignored

counter.dispatch(3) // works
counter.dispatch(-3) // won't work, it'll get ignored

지금은 그게 다입니다.

직접 사용해 보고 싶다면 여기 StackBlitz playground link이 있습니다.

NumUnit 단독으로 할 수 있는 일이 훨씬 더 많습니다. 다음은 이러한 기능 중 일부를 보여주는 기사입니다.





건배

🌏 ActiveJS Website
📖 ActiveJS Documentation
🤾‍♂️ ActiveJS Playground
💻 ActiveJS GitHub Repo (아마도 ⭐ 드롭 :)

좋은 웹페이지 즐겨찾기