레소, 세계에서 가장 간단한 주 매니저

18819 단어 reacthooksstorestate

1.resso, React 상태 관리가 이렇게 간단한 적이 없음
resso는 세계에서 가장 간단한 사용 방식을 제공하기 위해 React의 새로운 주 매니저이다.
reso는 수요에 따라 업데이트를 실현했다.사용하지 않은 데이터가 변경되면 구성 요소 업데이트를 영원히 터치하지 않습니다.
GitHub:https://github.com/nanxiaobei/resso
import resso from 'resso';

const store = resso({ count: 0, text: 'hello' });

function App() {
  const { count } = store; deconstruct first, then use
  return (
    <>
      {count}
      <button onClick={() => store.count++}>+<button>
    <>
  );
}
APIresso가 하나뿐이고 스토어 대상만 포장하고 다른 것은 아무것도 없다.
업데이트하려면 저장된 키를 다시 분배하기만 하면 됩니다.

2. React state 관리자는 어떻게 작동합니까?
상점이 있다고 가정하고 다른 구성 요소를 주입합니다.
let store = {
  count: 0,
  text: 'hello',
};

// Component A
const { count } = store;
const [, setA] = useState();

// Component B
const { text } = store;
const [, setB] = useState();

// Component C
const { text } = store;
const [, setC] = useState();

// init
const listeners = [setA, setB, setC];

// update
store = { ...store, count: 1 };
listeners.forEach((setState) => setState(store));
모든 구성 요소의 설정 상태를 하나의 그룹에 넣고 저장소를 업데이트할 때 listeners 모든 설정 상태를 호출하여 모든 구성 요소의 업데이트를 터치합니다.
어떻게 저장 데이터의 변화를 감시합니까?Redux의 dispatch 와 같은 공통 업데이트 함수를 제공할 수 있으며, 이 함수를 호출하면 업데이트됩니다.에이전트의setter를 사용하여 감청할 수 있습니다.
네, 거의 모든 주 매니저들이 이렇게 일합니다. 이렇게 간단합니다.예를 들어, Redux의 소스 코드: https://github.com/reduxjs/redux/blob/master/src/createStore.ts#L265-L268

3. 어떻게 업데이트 성능을 최적화합니까?
저장소를 업데이트할 때마다 listeners 의 모든 setState를 호출합니다. 이것은 성능 문제를 초래할 수 있습니다.
예를 들어 업데이트count할 때 이론적으로 A만 업데이트되고 이때 B와 C도 업데이트되지만 전혀 사용하지 않는다count.
어떻게 필요에 따라 업데이트합니까?선택기(예를 들어 ReduxuseSelector나 zustand의 구현)를 사용할 수 있습니다.
// Component A
const { count } = store;
const [, rawSetA] = useState();

const selector = (store) => store.count;
const setA = (newStore) => {
  if (count !== selector(newStore)) {
    rawSetA(newStore);
  }
};
다른 구성 요소와 마찬가지로 setA에 새 구성 요소listeners를 구독하면 구성 요소의'필요에 따라 업데이트'를 실현할 수 있습니다.
상기 함수도 프록시 Getter를 사용하여 실현할 수 있으며, 구성 요소의 '사용' 데이터는 Getter를 통해 알 수 있습니다.

4.resso는 내부에서 어떻게 실시합니까?
상기 실행 중, 모든 구성 요소에서 setState를 수집합니다.저장소를 업데이트할 때 데이터 비교를 통해 구성 요소를 업데이트할지 여부를 확인합니다.
reso는 새로운 아이디어를 사용했는데 실제로는 갈고리의 원시 개념에 더욱 부합된다.
let store = {
  count: 0,
  text: 'hello',
};

// Component A
const [count, setACount] = useState(store.count);

// Component B
const [text, setBText] = useState(store.text);

// Component C
const [text, setCText] = useState(store.text);

// init
const listenerMap = {
  count: [setACount],
  text: [setBText, setCText],
};

// update
store = { ...store, count: 1 };
listenerMap.count.forEach((setCount) => setCount(store.count));
useState를 사용하여 구성 요소에서 사용하는 저장소에서 데이터를 주입하고 저장소의 키마다 업데이트 프로그램 목록을 유지합니다.
각 구성 요소에서 수집된 집합 상태 수는 사용된 저장 데이터와 대응합니다.구성 요소 업데이트의 설정 상태만 수집하는 것이 아닙니다.
업데이트할 때 데이터 비교를 할 필요가 없습니다. 왜냐하면 업데이트 단원은 '데이터' 단계를 바탕으로 하는 것이지 '구성 요소' 단계를 바탕으로 하는 것이 아닙니다.
어떤 데이터를 업데이트하는 것은 구성 요소의 업데이트 프로그램 목록이 아니라 이 데이터를 호출하는 업데이트 프로그램 목록입니다.상점 전체가 다 있다.

5.resso의 API는 어떻게 설계되었습니까?
API를 설계하는 비결은 먼저 원하는 사용법을 작성한 다음에 그것을 어떻게 실현하는지 찾아내는 것이다.이로 인해 발생하는 결과는 반드시 가장 직관적이어야 한다.
reso는 처음에 다음과 같은 API 설계도 고려했습니다.
1. valtio와 유사
const store = resso({ count: 0, text: 'hello' });

const snap = useStore(store);
const { count, text } = snap; // get
store.count++; // set
이것은 갈고리의 표준 사용법으로 APIuseStore를 추가한 것이 단점이다.가져올 때 snap을 사용하고, 설정할 때 store를 사용하면 분열됩니다.이것은 절대로'가장 간단하다'는 방법이 아니다.
2.valtio/macro와 유사
const store = resso({ count: 0, text: 'hello' });

useStore(store);
const { count, text } = store; // get
store.count++; // set
이것도 실현할 수 있고 연결의 표준 용법이다.이 때 get과 set의 주체는 통일되지만 useStore API를 추가해야 합니다.이 물건은 갈고리만 호출하는 데 사용되는데, 만약 사용자가 그것을 작성하는 것을 잊어버리면 어떻게 합니까?
실천에서 우리는 모든 구성 요소에서store를 사용할 때 반드시 두 가지 물건을 가져와야 한다는 것을 발견했다. store와useStore는 하나의 저장소만 가져오는 것처럼 간단하지 않을 것이다. 특히 많은 구성 요소에서 그것을 사용할 때 매우 번거롭다.
3. 상점 하나만 들여오기 위해
const store = resso({ count: 0, text: 'hello' });

store.useStore();
const { count, text } = store; // get
store.count++; // set
이것은 '합법적' 으로 갈고리를 사용하는 마지막 희망이다. 단지 상점을 도입하는 것일 뿐이지만, 어쨌든, 그것은 여전히 이상하게 보이며, 사람들로 하여금 받아들일 수 없게 한다.
만약 이 API를 설계하려고 시도한다면, 저장소를 직접 업데이트하고 (저장소를 가져와야 한다), 그리고 갈고리에서 저장된 데이터를 해체하고 싶다면 (갈고리를 하나 더 가져와야 하고, get과 set은 다른 원본에서 가져와야 한다), 어쨌든 디자인은 서투르게 보일 것이다.
최종적인 단순성과 가장 간단한 사용 방식을 실현하기 위해 reso는 최종적으로 이 API 설계를 시작했다.
const store = resso({ count: 0, text: 'hello' });

const { count } = store; // get
store.count++; // set

6.resso를 어떻게 사용합니까?
상점에 가다
저장 데이터는 useState를 사용하여 구성 요소를 주입하기 때문에 먼저 해체(해체는 호출useState를 하고 구성 요소의 맨 위에서 해체(갈고리 규칙, if 이후에 쓸 수 없음)를 한 다음에 사용해야 한다. 그렇지 않으면 React 경고가 발생한다.
스토리지 설정
저장된 데이터의 첫 번째 레벨에 할당되면 업데이트가 트리거되고 첫 번째 레벨의 할당에만 업데이트가 트리거됩니다.
store.obj = { ...store.obj, num: 10 }; // ✅ trigger update

store.obj.num = 10; // ❌ does not trigger update (valtio supports this way)
resso는valtio와 같은 쓰기 방법을 지원하지 않습니다. 주로 다음과 같은 고려에서 비롯됩니다.
  • 모든 데이터를 에이전트에 깊이 파고들고 데이터를 업데이트할 때 먼저 에이전트를 해야 하기 때문에 일정한 성능 손실을 초래할 수 있다.(초기화할 때, reso는 프록시 저장소를 한 번만 저장합니다.)
  • 모든 데이터가 프록시 데이터이기 때문에 크롬 콘솔에서 인쇄할 때 우호적이지 않은 것이 큰 문제입니다.(resso는 저장소만 에이전트이기 때문에 보통 저장소의 데이터를 출력합니다.)
  • 만약에 하위 데이터가 해체된다면 objobj.num = 10도 업데이트를 촉발할 수 있다. 그러면 데이터 원본이 투명하지 않고 저장에서 왔는지, 분배에서 업데이트를 촉발했는지 확실하지 않다.(resso의 주체는 항상 상점에서 왔고 출처도 분명하다.)

  • 7.간단하다.혼란이 아니에요.
    이상은 reso의 디자인 개념과 React 상태 관리자의 일부 실현이다.
    결국 React 상태 관리자는 하나의 도구이고 React는 하나의 도구이며 JS는 하나의 도구이며 프로그래밍은 하나의 도구이며 작업 자체는 하나의 도구이다.
    도구의 목적은 도구 자체가 아니라 현실 세계에 작용하는 작품을 창조하는 것이다.
    그럼, 왜 간소화하지 않습니까?
    jQuery는 원생 JS의 개발을 간소화하기 위한 것이고React는 jQuery의 개발을 간소화하기 위한 것이다. 개발은 현실 세계의 과정을 간소화하기 위한 것이다. 인터넷은 사람들의 교류 경로, 작업 경로, 소비 경로를 간소화하기 위한 것이다. 개발의 의미는 간소화이고 인터넷 자체의 의미는 간소화이며 인터넷의 가치는 간소화에 있다.
    그럼, 왜 간소화하지 않습니까?
    독특하다.극객이 아니다.

    간단함이 전부다.
    reso:https://github.com/nanxiaobei/resso

    좋은 웹페이지 즐겨찾기