reducer w osobnym pliku?

0

Mam komponent, którego kod to jakieś 120 linii. Do zarządzania jego stanem używam hooka useReducer. Kod reducera wraz z initalState i selectors również zajmuje jakieś 120 linii, przez co cały plik ma ponad 250 linii. Czy w takiej sytuacji lepiej jest przenieść kod dotyczący stanu komponentu do osobnego pliku, czy może lepiej pozostawić go tak jak jest?

1

Nie widzę powodu dla którego miałbyś to trzymać razem. Rozdzielenie tego kodu spowoduje wzrost jego czytelności i dostępności. Zdecydowanie łatwiej przegląda się kod aplikacji rozbity na mniejsze pliki niż zbity w jeden monolit.

0

@Haskell Tylko że to wtedy będzie sztuczne oddzielenie logiki zarządzania stanem od komponentu, którego ten stan dotyczy. Ale tak, też mi się wydaje, że lepiej to wydzielić, szukałem potwierdzenia.

A jeśli już wydzielać, to jak? Stworzyć sobie folder z plikami reducer, actions, Component, index?

2
nobody01 napisał(a):

Mam komponent, którego kod to jakieś 120 linii. Do zarządzania jego stanem używam hooka useReducer. Kod reducera wraz z initalState i selectors również zajmuje jakieś 120 linii, przez co cały plik ma ponad 250 linii. Czy w takiej sytuacji lepiej jest przenieść kod dotyczący stanu komponentu do osobnego pliku, czy może lepiej pozostawić go tak jak jest?

Nie patrz na pliki, tylko na funkcje i użyte zmienne. Na zależności między funkcjami. Np. weźmy taki wymyślony przykład:

let something = 20;

function Foo({ foo }) {
    const [state, dispatch] = useReducer(() => {
         return 123 + something + foo;
    }, 0);
    return <div>{ something }</div>
}

z kodem powyżej jest kilka problemów, choćby taki, że reducer jest w środku komponentu (więc nie można go wykorzystać w innym miejscu apki)

Można by go więc przenieść poza komponent Foo:

let something = 20;
const reducer = () => {
         return 123 + something + foo; // ERROR!
 },
function Foo({ foo }) {
    const [state, dispatch] = useReducer(reducer, 0);
    return <div>{ something }</div>
}

Ale wtedy nie zadziała, bo nie odnajdzie zmiennej foo. Więc, żeby reducer można było użyć w innych miejscach, należałoby przekazywać wartość foo przy każdym wywołaniu funkcji za pośrednictwem akcji. Czyli większy decoupling.

Ale teraz - jak ktoś będzie chciał użyć naszego reducera, to będzie musiał importować plik z komponentem. Trochę dziko i może to rodzić dziwne zależności (bo po co ktoś ma importować plik z komponentem, jeśli chce użyć tylko reducera?). Przy odrobinie nieuwagi możemy nawet doprowadzić do nieszczęsnej cyklicznej zależności (jeśli chcielibyśmy użyć w komponencie Foo z pliku foo.js komponent Bar z pliku bar.js, i jeśli komponent Bar też korzystałby z tego samego reducera - to by znaczyło, że plik bar.js musiałby importować plik foo.js. Czyli cykliczna zależność).

Dlatego lepiej, żeby reducer znajdował się w osobnym pliku. Ale znowu. Nie możemy tego zrobić ot tak, bo reducer korzysta ze zmiennej something (z której korzysta również komponent Foo), więc musimy pomyśleć, co zrobić ze zmienną something (być może przenieść ją razem z reducerem? A może przenieść ją do jeszcze innego pliku?).

Więc... generalnie o to chodzi w tym całym "co ma być w osobnym pliku, a co w innym". Nie o to, czy ładnie wygląda. Tzn. niby to też, ale ważniejsze jest to, że trzymanie rzeczy "osobno" (czy to w osobnym pliku, czy w osobnej funkcji itp.) pozwala na używanie tego w wielu miejscach i sytuacjach. A trzymanie rzeczy razem wiąże rzeczy ze sobą, że ich potem nie oddzielisz. A im później zaczniesz oddzielać, tym trudniej będzie to zrobić.

Dzielenie na moduły pomaga, bo wtedy jak chcesz coś użyć z innego pliku, to musisz to świadomie zaimportować. Więc masz większą kontrolę (chociaż samo dzielenie na moduły może g**no dać, jeśli będziesz importować wszystko jak leci. Wtedy możesz mieć wszystko w osobnych modułach, ale będziesz miał taki sam burdel, jeśli każdy moduł będzie importować z kilkanaście innych...)

nobody01 napisał(a):

@Haskell Tylko że to wtedy będzie sztuczne oddzielenie logiki zarządzania stanem od komponentu, którego ten stan dotyczy.

Możesz nawet w tym samym katalogu, co masz komponent, utworzyć plik z logiką. Nie będzie sztucznie oddzielony.

Aczkolwiek nie jestem radykałem. Mimo tego, co napisałem wyżej, to ja lubię na samym początku pisać wszystko w jednym pliku i potem dopiero stopniowo rozdzielać rzeczy, robić refaktoring (bo jak coś jest małego to łatwiej mi się pracuje na całym pliku naraz niż za każdym razem tworzyć osobny plik). Poza tym czasem lubię powiązane ze sobą rzeczy (np. kilka podobnych komponentów) po prostu trzymać w jednym pliku. Ale koniec końców nie chodzi o "czy to jest w jednym pliku, czy w kilku" tylko o decoupling, separation of concerns, single responsibility principle itp. Jak to jest zachowane, to ew. podzielenie na moduły później jest łatwe (jeśli nie jest zachowane, to można zrefaktorować, żeby było).

Oczywiście kwestie estetyczne / czytelności też są istotne, jeśli plik robi się za duży, to niewygodnie jest go czytać. To też prawda.

1 użytkowników online, w tym zalogowanych: 0, gości: 1