조태야, 지금 광학에 종사하고 있어.

점점 더 많은 functional paradigms명이 우리의 청부 업무에 들어갔다.얼마 전, 우리가 React Hooks을 사용하기 시작했을 때, 이것은 확실히 속도를 높였다.사실 그날, 우리의 임무는 이전에 작성한 Angular ThreeJS 유류 프로젝트를 React/react-three-fiber으로 전환하여 성능, 유지보수가 용이하도록 하는 것이다. 날로 증가하는 복잡성을 고려하여 우리는 더욱 원자적이고 조합할 수 있는 상태 관리 시스템을 원한다. (물론 이것은 Recoil을 도입하기 전이다.)몇몇 직무를 다하는 조사를 거쳐 우리는 Grammarly's Focal을 확정하였다.이 라이브러리는 좀 낡았지만 기능이 강해서 FP, Optics 등 재미있는 Lenses 개념을 우리에게 소개하였다
현재 우리는 Jotai에 대한 더 많은 정보를 알고 있습니다. RecoilPoimandres의 대체품(react-three-fiber의 창작자 등)입니다.말할 것도 없이, 우리가 우연히 Jotai Issue #44을 발견했을 때, 우리는 매우 흥분했다. Meris Bahtijaragic은 원자에 초점을 맞출 수 있는 토론을 시작했고, jotai-optics은 사람들의 주목을 끄는 작업이었다.이 코드는 우리가 최근에 줄곧 흥미를 가지고 있는 또 다른 라이브러리 optics-ts을 봉인하여 새로운 수준의 유형의 보안 기능을 제공하였다.
현재 Optics의 개념이 당신에게 새로운 것이라면 함수 프로그래밍의 상하문에서 좋은 소개가 있습니다.그 중 간결한 예는 렌즈와 프리즘의 @gcanti's article, 그리고 plenty more이다.John DeGoes' Glossary of Functional Programming은 새로운 FP 어휘를 배우는 데도 도움을 줄 것이다.그러나 우리의 이 졸렬한 목표는 더 많은 실용 (학술) 예시를 제공하는 것이다.
이 새로운 기능을 탐색하기 위해서 우리는 기존의 반충 예시를 사용할 것이다.우리는 Jotai으로 전환할 뿐만 아니라, jotai-optics (과 optics-ts )의 장점을 소개하기 위해 추가 기능을 추가할 것이다.
이 연습에 대해 우리는 Diogo Gancalves' cool Joeflix 응용 프로그램을 JotaiFlix으로 업그레이드하는 것이 재미있을 것이라고 생각합니다!

시작합시다.
우선, 우리는 RecoilRoot으로 Provider을 교체해야 한다
// App.js exceprt
...
//import {RecoilRoot} from 'recoil'
import { Provider } from "jotai";

...

function App() {
  return (
    /* <RecoilRoot> */
    <Provider>
    <JotaiDebugger />
      <Router>
        <FeedbackPopup />
...
그런 다음 UI에 즐겨찾기 및 기록을 추가합니다.이것은 우리에게 특정한 사용자가 생성하는 상태를 주고 우리의 광학은 행동을 취할 수 있다.이를 실현하기 위해서는 우선 조태 원자를 만들어 이 상태를 저장해야 한다.우리가 그것을 사용할 때, 우리는 약간의 기본값을 포함할 것이다.
// state.js excerpt
...
export const historyAtom = atom([
    {id: 62286, title: "Fear the Walking Dead", desc: "What did the world look like as it was transformin… the end of the world, will answer that question.", banner: "/58PON1OrnBiX6CqEHgeWKVwrCn6.jpg", type: "tv"},
    {id: 528085, title: "2067", desc: undefined, banner: "/5UkzNSOK561c2QRy2Zr4AkADzLT.jpg", type: "movie"}
])

export const favoritesAtom = atom([
    {id: 590223, title: "Love and Monsters", desc: undefined, banner: "/lA5fOBqTOQBQ1s9lEYYPmNXoYLi.jpg", type: "movie"},
    {id: 76479, title: "The Boys", desc: "A group of vigilantes known informally as “The Boys” set out to take down corrupt superheroes with no more than blue-collar grit and a willingness to fight dirty.", banner: "/mGVrXeIjyecj6TKmwPVpHlscEmw.jpg", type: "tv"}
])
...
현재 우리는 주어진 영화/프로그램이 이미 즐겨찾기나 역사 집합에 포함되어 있는지 확인하는 함수가 필요하다.존재하면 삭제하고, 존재하지 않으면 추가합니다.
여기서 무슨 일이 일어났는지 얘기해 봅시다.간단히 말하면 우리는 jotai-optics 포장된 optics-ts isomorphism을 사용하여 외부 focus에서 전달된 내부로 전달된 원자 집합을 변환한다.
현재와 변환된 볼 값을 추적해야 하기 때문에 광학에서 두 가지 속성(containedvalue)을 가진 포장 대상을 만들었습니다.contained 속성 추적 광학 소자 볼 출력, value 속성 추적은 지정한 항목의 그룹을 포함할 수 있습니다.
// optics.js
export const containsOptic = (item) => {

    return O.optic()
        .iso(
            // Lens that is isomorphically converting an array given an item 
            // to a boolean determining whether the array contains that item.
            (val) => ({ 
                contained: (item && item.id) ? (_.findIndex(val, (currentItem) => item.id == currentItem.id) > -1) : false,
                value: val
            }),
            (obj) => {
                if(!(item && item.id)) {
                    return collection;
                }

                const collection = _.clone(obj.value);

                const index = _.findIndex(collection, (currentItem) => item.id == currentItem.id);

                if(obj.contained && index < 0) {
                    collection.push(item);
                } else if(!obj.contained && index > -1) {
                    collection.splice(index, 1);
                }

                return collection;
            }
        )
        .prop('contained');
BigTile.js, Tile.jsHero.js 파일의 일을 상대적으로 간단하게 하기 위해서, 우리는 위의 containsOptic 공장 함수를 호출하여 광학 소자를 실례화하는데, 이것은 역사와 가장 좋아하는 상태를 제공할 뿐만 아니라, 그것을 쉽게 설정하는 방법을 제공한다.
// Tile.js excerpt

...
function Tile({data}) {

    // https://github.com/merisbahti/jotai-optics
    const [isInHistory, setIsInHistory] = 
        useAtom(focus(historyAtom, optic => optic.compose(containsOptic(data))))
    const [isFavorite, setIsFavorite] = 
        useAtom(focus(favoritesAtom, optic => optic.compose(containsOptic(data))))

마지막으로, 우리는 상기 icon 단추를 추가하여 상기 jotai-optics focus 방법으로 만든 상응하는 setter를 호출하여 즐겨찾기와 역사 상태를 바꿀 것입니다.
// Continued Tile.js excerpt

    const toggleFavorites = () => {
        setIsFavorite(!isFavorite);
    }
    const playMedia = () => {
        setIsInHistory(!isInHistory);
    }

    ...
    <button className="tile__play"  onClick={() => toggleFavorites()}>
        {isFavorite ? <AiFillHeart /> : <AiOutlineHeart />}
    </button>
    ...
    <button className="tile__play" onClick={playMedia}>
        <img className="tile__icon" src={require('../images/[email protected]')} alt=""/>
    </button>
...
그렇습니다!

마지막 생각:

  • optics의 실현을 바탕으로 상태 돌연변이가 모듈화되고 간결할 수 있도록 확보한다.
  • @akeron optics-ts 라이브러리를 사용하여 강력한 광학 부품을 구축하여 중복되기 쉬운 도안과 깨끗한 구조를 형성할 수 있다

  • @merisbahti jotai-optics 은 좌태와 optics-ts 간의 직접적인 통합을 제공한다.
  • 은 분명히 이것은 매우 간단한 통합이지만, 우리는 Jotaijotai-optics 사이의 강력한 함수 프로그래밍 통합으로 문을 열었다고 생각한다. 특히 optics-ts의 인상적인 기능 집합을 고려하면
  • Codesandbox example은 아래에 포함되어 있습니다.
    주의: 이 예시 코드는 Jotai Dev Tools을 포함하므로 Redux DevTools Browser Extension을 사용하여 관련 상태 변화를 쉽게 관찰할 수 있도록 하십시오.자세한 내용은 를 참조하십시오.

    좋은 웹페이지 즐겨찾기