어떻게 재발에서 반격으로 전환합니까

31666 단어 reactjavascript
React에서 복잡한 상태를 관리하는 것은 때때로 어려울 수 있습니다. 이것이 바로 우리들 중 일부가 Redux나 유사한 라이브러리(예를 들어 MobX)를 사용해서 React의 상태를 관리하는 이유입니다.Recoil은 React의 Hooks API와 밀접한 관계를 가진 또 다른 상태 관리 라이브러리입니다.공유 상태를 원자로 정의하고 계산 상태를 선택기로 정의할 수 있습니다.페이스북 팀이 직면한 한계와 그들이 어떻게 반격으로 이 문제를 해결하려고 하는지 알고 싶다면 이것을 보십시오.
중요한 주의사항은 페이스북을 비롯한 많은 회사들이 Recoil을 사용하고 있지만 기술적으로 실험 상태여서 API와 기능이 달라질 수 있다는 것이다.
이 문서에서 Redux에서 Recoil로 전환하는 방법과 이 과정에서 차이를 비교하는 방법을 보여 드리겠습니다.Redux의 GitHub repository에 있는 TodoMVC 예를 사용하겠습니다.당신은 내가 당신을 위해 만든 link을 사용하여 zip 파일을 다운로드할 수 있습니다😉. 다음은 애플리케이션의 작동 방법입니다.

역극 설정


모든 JavaScript 라이브러리를 사용하는 첫 번째 단계는 프로젝트에 추가하는 것입니다.HTML <script> 태그를 사용하여 참조를 추가하거나 npm을 통해 설치할 수 있습니다.npm 스타일의 프로젝트를 다운로드했기 때문에 npm install recoil 또는 yarn add recoil을 실행하여 Recoil을 설치하십시오.
Redux를 사용하는 것과 유사하게, 우리는 <Provider />으로 루트 부품을 포장하고, 우리는 <RecoilRoot />으로 그것을 교체할 것이다. 이렇게 하면 부품은 반충 상태를 사용할 수 있다.
src/index를 엽니다.js를 RecoilRoot 모듈로 가져옵니다.
import { RecoilRoot } from "recoil";
그런 다음 다음과 같이 렌더링 함수를 업데이트합니다.
render(
  <RecoilRoot>
    <App />
  </RecoilRoot>,
  document.getElementById("root")
);

상태 정의 및 업데이트


한 주를 표시하기 위해서, 당신은 atom을 성명해야 합니다.TODO 목록을 저장하려고 하므로 기본 또는 초기 상태의 atom을 만듭니다.새 충돌 디렉터리를 만들고 todos라는 새 파일을 추가합니다. 다음 내용을 포함합니다.
import { atom } from "recoil";

export const todos = atom({
  key: "todos",
  default: [],
});
구성 요소/제목을 엽니다.js는 다음 코드로 업데이트됩니다.
import React from "react";
import TodoTextInput from "./TodoTextInput";
import { useSetRecoilState } from "recoil";
import { todos } from "../recoil/todos";

const Header = () => {
  const setTodos = useSetRecoilState(todos);

  const save = (text) => {
    if (text.length !== 0) {
      setTodos((todos) => [
        ...todos,
        {
          id: Date.now(),
          text,
          completed: false,
        },
      ]);
    }
  };

  return (
    <header className="header">
      <h1>todos</h1>
      <TodoTextInput
        newTodo
        onSave={save}
        placeholder="What needs to be done?"
      />
    </header>
  );
};

export default Header;
어셈블리에는 새 TODO를 수집하고 저장할 텍스트 입력이 표시됩니다.새로운 todo를 추가하려면 todos 상태의 내용을 업데이트하는 함수가 필요합니다.우리는 useSetRecoilState() 갈고리를 사용하여 setter 함수를 얻는데, 이 함수는 save() 함수에서 사용된다.11줄에서 setter 함수의 업데이트 형식을 사용했습니다. 그러면 오래된 TODO를 기반으로 새로운 목록을 만들 수 있습니다.이것이 바로 우리가 처리해야 할 일을 수집하고 저장하는 데 필요한 모든 것이다.
Redux와 비교하려면 작업 작성자와 복원기를 만들어 상태를 업데이트한 다음 구성 요소를 Redux 저장소에 연결하고 작업을 할당해야 합니다.역충돌에서 데이터를 저장할 원자를 정의한 다음 hooks API를 사용하여 데이터와 상호작용합니다.React와 hooks API에 대해 잘 모르면 Recoil을 빨리 파악해야 합니다. React의 API와 밀접한 관계가 있기 때문에 Redux처럼 일방적인 데이터 흐름의 스타일을 이해해야 하지 않습니다.

파생 상태


응용 프로그램에서 업데이트할 다음 부분은 <MainSection /> 구성 요소입니다.모든 TODO를 완료됨으로 표시하는 입력과 두 개의 추가 구성 요소를 보여 줍니다. 다음에 설명하겠습니다.그래서 componenrs/MainSection을 엽니다.js 및 다음 코드를 사용하여 업데이트합니다.
import React from "react";
import { useRecoilValue, useRecoilState } from "recoil";
import Footer from "./Footer";
import VisibleTodoList from "../containers/VisibleTodoList";
import { completedTodoCount, todos } from "../recoil/todos";

const MainSection = () => {
  const completedCount = useRecoilValue(completedTodoCount);
  const [todoList, setTodoList] = useRecoilState(todos);
  const todosCount = todoList.length;

  const clearCompleted = () => {
    setTodoList((previousTodos) =>
      previousTodos.filter((todo) => todo.completed === false)
    );
  };

  const completeAllTodos = () =>
    setTodoList((previousTodos) => {
      const areAllMarked = previousTodos.every((todo) => todo.completed);
      return previousTodos.map((todo) => ({
        ...todo,
        completed: !areAllMarked,
      }));
    });

  return (
    <section className="main">
      {!!todosCount && (
        <span>
          <input
            className="toggle-all"
            type="checkbox"
            checked={completedCount === todosCount}
            readOnly
          />
          <label onClick={completeAllTodos} />
        </span>
      )}
      <VisibleTodoList />
      {!!todosCount && (
        <Footer
          completedCount={completedCount}
          activeCount={todosCount - completedCount}
          onClearCompleted={clearCompleted}
        />
      )}
    </section>
  );
};

export default MainSection;
우리가 여기서 한 것은 Redux에 연결되어 mapStateToPropsmapDispatchToProps을 호출하지 않고 두 개의 반충 연결을 사용했는데 각각 useRecoilValueuseRecoilState이다.useRecoilValue() 함수는 상태의 내용을 읽는 데 사용한다.우리의 상황은 completedTodoCount이다.우리는 todos의 상태를 얻고 이를 갱신할 수 있기를 희망한다.이를 위해, 우리는 useRecoilState()을 사용하여 todos을 읽고, 함수를 얻어 그것을 업데이트합니다.우리는 clearCompleted()completeAllTodos()의 두 가지 함수를 가지고 있으며, 상태를 업데이트하는 데 사용된다.completedTodoCount 상태를 정의해야 합니다.이는 todos 상태에 따라 계산해야 한다.이를 위해 이른바 '뒷좌석 선택기' 를 만들 것입니다.오픈 후 좌력/todos.js를 반충 패키지에서 선택기를 가져옵니다.
import { atom, selector } from "recoil";
그런 다음 다음과 같이 선택기를 정의합니다.
export const completedTodoCount = selector({
  key: "completedTodoCount",
  get: ({ get }) => {
    const list = get(todos);

    return list.reduce(
      (count, todo) => (todo.completed ? count + 1 : count),
      0
    );
  },
});
선택기를 정의하려면 상태 이름을 포함하는 대상과 값을 계산하고 되돌려 주는 selector() 함수를 get() 함수로 호출할 수 있습니다.이 함수는 get() 함수를 가진 대상을 수신하는데, 이 함수는 다른 원자나 선택기에서 데이터를 검색하는 데 사용할 수 있다.

작업 필터링


현재 저는 반충의 대부분 기초 지식을 소개했습니다. Redux와 어떤 차이가 있는지 보실 수 있지만 React의 Hooks API와 밀접한 관계가 있습니다.이 글의 나머지 부분은 프로그램이 반충 기능을 완전히 사용할 수 있도록 코드만 추가할 것이다.
우리가 연구하고자 하는 다음 부품은 <FilterLink />부품이다.컨테이너/필터 링크를 엽니다.js 및 다음 코드로 파일을 업데이트합니다.
import React from "react";
import { useRecoilState } from "recoil";
import Link from "../components/Link";
import { visibilityFilter } from "../recoil/todos";

export default ({ filter, children }) => {
  const [visibility, setVisibilityFilter] = useRecoilState(visibilityFilter);
  const setFilter = () => setVisibilityFilter(filter);

  return (
    <Link
      active={filter === visibility}
      setFilter={setFilter}
      children={children}
    />
  );
};
여기에는 표시할 TODO의 입력을 필터링하는 방법을 선택하는 <Link /> 구성 요소가 나와 있습니다.생성되지 않은 새 상태를 사용했기 때문에 추가할 것입니다.오픈 후 좌력/todos.js 및 다음 기능을 추가합니다.
import {
  SHOW_ALL,
  SHOW_COMPLETED,
  SHOW_ACTIVE,
} from "../constants/TodoFilters";

export const visibilityFilter = atom({
  key: "visibilityFilter",
  default: SHOW_ALL,
});

업무 표시


다음 작업은 설정된 필터에 따라 TODO를 표시하는 것입니다.이를 위해, 우리는 새로운 선택기를 추가하고 <VisibleTodoList /> 구성 요소를 업데이트할 것입니다.네가 아직 뒷좌석이 있을 때.js open, 다음 선택기를 추가합니다.
export const filteredTodos = selector({
  key: "filteredTodos",
  get: ({ get }) => {
    const filter = get(visibilityFilter);
    const list = get(todos);

    switch (filter) {
      case SHOW_COMPLETED:
        return list.filter((t) => t.completed);
      case SHOW_ACTIVE:
        return list.filter((t) => !t.completed);
      default:
        return list;
    }
  },
});
컨테이너/액세스 가능한 목록을 엽니다.js 및 다음 코드로 파일을 업데이트합니다.
import React from "react";
import TodoList from "../components/TodoList";
import { filteredTodos, todos } from "../recoil/todos";
import { useRecoilValue, useSetRecoilState } from "recoil";

const VisibleTodoList = () => {
  const filteredTodoList = useRecoilValue(filteredTodos);
  const setTodos = useSetRecoilState(todos);

  const completeTodo = (todoId) => {
    setTodos((previousTodos) =>
      previousTodos.map((todo) =>
        todo.id === todoId ? { ...todo, completed: !todo.completed } : todo
      )
    );
  };

  const deleteTodo = (todoId) => {
    setTodos((previousTodos) =>
      previousTodos.filter((todo) => todo.id !== todoId)
    );
  };

  const editTodo = (todoId, text) => {
    setTodos((previousTodos) =>
      previousTodos.map((todo) =>
        todo.id === todoId ? { ...todo, text } : todo
      )
    );
  };

  return (
    <TodoList
      filteredTodos={filteredTodoList}
      actions={{ completeTodo, deleteTodo, editTodo }}
    />
  );
};

export default VisibleTodoList;
여기에 todo를 삭제하거나, 업데이트하거나, 완성된 것으로 표시하는 세 가지 함수를 추가했습니다.이러한 함수는 Redux에서 동작과 감축 함수의 조합으로 볼 수 있습니다.나는 함수와 그것을 필요로 하는 구성 요소를 같은 파일에 두기로 결정했지만, 원한다면 그것들을 단독 파일로 압축할 수 있다.
이 점에서, Redux가 아닌 역충돌을 사용하는 프로그램을 업데이트했습니다.마지막 일은 구성 요소/응용 프로그램을 업데이트하는 것입니다.js.이 파일을 열고 <Header /><MainSection /> 구성 요소의 가져오기 문을 변경합니다.
import Header from "./Header";
import MainSection from "./MainSection";
현재 당신은 이 todo 프로그램을 가지고 있으며, Redux를 사용하여 반동을 통해 업데이트되었습니다.

결론


이 프로그램을 Redux에서 Recoil로 이동하는 것은 내가 상상했던 것처럼 그렇게 복잡하지 않다.나는 네가 Redux 상태를 설계하는 방식과 다른 몇 가지 요소에 따라 너의 모든 응용 프로그램이 그렇지 않다고 생각한다.그러나 익숙한 React API에 따라 모델링된 것이기 때문에 새로운 응용 프로그램에 사용하기 쉽다고 생각합니다.
반격에 대한 자세한 내용은 recoiljs.org에서 확인할 수 있습니다.너는 GitHub에서 완전한 응용 프로그램과 원본 코드를 찾을 수 있다.
최초 출시: Telerik

좋은 웹페이지 즐겨찾기