Jotai(완전 Redux는 아님) 개발 도구
현재, 대다수 사람들과 마찬가지로, 우리는 기능이 강하고 통용되는 개발 도구, 예를 들면 React DevTools, React Query DevTools 등을 즐겨 사용한다. 비록 우리는 과거에 생산 능력에서 Redux 을 사용하지 않았지만, 우리는 시종 ReduxDevTools 디버깅 React 상태 관리 시스템을 더욱 즐겨 사용한다.사실상, 우리는 계약 업무에서 사용하는 모든 주 관리 시스템을 위해 사용자 정의 내부 플러그인을 만들었다.본문을 작성할 때 우리는 아직 조태 플러그인을 찾지 못했기 때문에 자연스레 조태 플러그인을 만드는 것이 서로 영향을 미칠 수 있다고 생각한다.
우선 Config, Message, ConnectionResult, Extension 등에 Redux DevTools에서 Redux DevTools로 전송되는 유효 부하와 일치하는 인터페이스/유형을 설정했습니다.이 인터페이스들은 Browser Extension 본체와 통신하는 강한 유형의 맵을 지원한다.
interface Config {
instanceID?: number,
name?: string,
serialize?: boolean,
actionCreators?: any,
latency?: number,
predicate?: any,
autoPause?: boolean
}
interface Message {
type: string,
payload?: any,
state?: any
}
interface IConnectionResult {
subscribe: (dispatch: any) => {};
unsubscribe: () => {};
send: (action: string, state: any) => {};
error: (payload: any) => {};
}
type ConnectionResult = IConnectionResult & Observable<Message>
interface Extension {
connect: (options?: Config) => ConnectionResult;
}
불행하게도 브라우저 확장 전단에 사용되는 Redux DevTools connect 함수는 표준 RxJS 관찰 가능한 값을 되돌려 주지 않았습니다.따라서 RxJS가 호환되는 관찰 가능한 대상이 Redux DevTools 이벤트를 수신할 수 있도록 wrapConnectionResult
함수가 필요합니다.const wrapConnectionResult = (result: ConnectionResult) => {
const subject = new Subject<Message>()
result.subscribe(
(x: any) => subject.next(x),
(x: any) => subject.error(x),
() => {subject.complete()}
);
return subject;
}
이제 사용자는 DevTools 인스턴스를 명명하고 구성할 수 있도록 JotaiDevtoolsProps
인터페이스를 구현할 것입니다.interface JotaiDevtoolsProps {
atom: WritableAtom<any, any>,
name?: string,
config?: Config
}
React 기능 구성 요소와 틈새 없는 통합을 실현하기 위해 갈고리를 만들었습니다. 이 갈고리는 우리의 Jotai Devtools Props를 가져와 특정한 Jotai atom의 실례를 실례화합니다....
export const useJotaiDevtools = ({ atom, name, config, ...props }: JotaiDevtoolsProps) => {
...
다음은 observable-hooks
라이브러리의 useObservable
hook 를 사용하여 RxJS의 관찰 가능한 값으로 전송된 원자의 값을 제공할 것입니다. const atom$ = useObservable((input$) => input$.pipe(
map(([x]) => x)
), [atomCurrentValue]);
원자 업데이트 시 충돌 상황을 방지하기 위해 마지막 상태 업데이트가 Redux DevTools 시간 여행 이벤트인지 확인하기 위해 로고를 추가합니다. const [wasTriggeredByDevtools, setWasTriggeredByDevtools] = useState(() => false);
또한 초기 상태가 DevTools 확장으로 전송되었는지 확인하는 플래그가 필요합니다. const [sentInitialState, setSentInitialState] = useState(() => false);
const [devTools, setDevTools] = useState<ConnectionResult>();
DevTools 연결은 갈고리를 초기화할 때 사용할 수 없기 때문에 연결이 완료될 때 정리된 이벤트 흐름을 제공하기 위해 다른 useObservable
를 추가합니다. const devTools$ = useObservable((input$) => input$.pipe(
filter(([x]) => !!x),
switchMap(([x]) => wrapConnectionResult(x as ConnectionResult)),
catchError((error, observable) => {
console.error(error);
return observable;
})
), [devTools]);
이 함수는 상태 점프와 시간 여행 이벤트를 처리하는 데 사용됩니다. const jumpToState = (newState: any) => {
setWasTriggeredByDevtools(true)
// var oldState = atomCurrentValue();
setAtom(newState);
// setWasTriggeredByDevtools(false);
};
이전 모드를 계속하면 observable-hook
의useSubscription 갈고리를 사용하여 DevTools 확장 이벤트를 구독하고 현지 응답 시작이나 스케줄링 작업에 적합합니다. useSubscription(devTools$, (message) => {
switch (message.type) {
case 'START':
console.log("Atom Devtools Start", options.name, atomCurrentValue)
if(!sentInitialState) {
// devTools.send("\"" + options.name + "\" - Initial State", atom.getState());
devTools?.send(name + " - Initial State", atomCurrentValue);
setSentInitialState(true);
}
return;
case 'DISPATCH':
if (!message.state) {
return;
}
switch (message.payload.type) {
case 'JUMP_TO_ACTION':
case 'JUMP_TO_STATE':
jumpToState(JSON.parse(message.state));
return;
}
return;
}
});
다음은 현재 Jotai atom의 응용 프로그램 상태 변경에 대한 업데이트를 구독하기 위한 또 다른 useSubscribe
갈고리가 필요합니다. useSubscription(atom$, (state) => {
if (wasTriggeredByDevtools) {
setWasTriggeredByDevtools(false);
return;
}
devTools?.send(name + " - " + moment().toISOString(), state);
})
구성 요소를 초기화할 때, DevTools Extension 에 대한 인용을 얻기 위해 함수가 필요합니다.확장자가 설치되어 있지 않으면 콘솔에 오류가 기록됩니다. const initDevtools = () => {
const devtools = (window as any).__REDUX_DEVTOOLS_EXTENSION__ as Extension;
// const options = config;
const name = options.name || window.document.title;
if (!devtools) {
console.error('Jotai Devtools plugin: Cannot find Redux Devtools browser extension. Is it installed?');
return atom;
}
const devTools = devtools.connect(options);
console.log("Get Dev Tools", devTools, of(devTools));
setDevTools(devTools);
// setTimeout(() => devTools.send(name + " - Initial State", atomCurrentValue), 50)
return atom;
}
우리의 초기화 함수를 활성화하기 위해서, 우리는 useLifeCycles
갈고리 (우수한 react-use 라이브러리) 를 이용하여 구성 요소가 불러오는 생명주기 이벤트를 처리할 것이다. useLifecycles(() => {
initDevtools();
});
그렇습니다.현재 사용Jotai Devtools plugin 항목에 새 Jotai atoms 만 설치하면 됩니다.구체적으로 말하자면, 우리는 당신이 Devtool Browser Extension에서 보고 싶은 모든 원자 호출
useJotaiDevtools
갈고리를 제공할 수 있습니다...
useJotaiDevtools({
name: "Dark Mode",
atom: darkModeState
});
...
useJotaiDevtools({
name: "Tasks",
atom: tasksAtom
});
...
설명을 위해 에서 Recoil 로 변환된 Jotai 예시를 반복해서 사용할 수 있습니다.프로그램이 시작되면 Redux DevTools Browser Extension 을 열 수 있습니다. 상태 변화, 시간 여행 디버깅 등을 볼 수 있습니다.마지막 생각:
observable-hooks
라이브러리를 이용하여 깨끗하고 효율적인 Redux DevTools 통합을 실현하였다.Reference
이 문제에 관하여(Jotai(완전 Redux는 아님) 개발 도구), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/c0d3t3k/jotai-not-exactly-redux-dev-tools-57i6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)