Czy Consumer to komponent wyższego rzędu?

0

Czy Consumer z Context Api w React to HOC (komponent wyższego rzędu) ?

1

Nie ma dokładnej definicji czym jest "HoC" ani czym jest "HoC w Reacie", pozostaje więc luźna interpretacja, że "higher order component" to taki component który może być scope wyżej (być rodzicem) innych komponentów.

Więc to znaczy, że:

  • Albo każdy komponent w Reacie jest HoC (bo każdy komponent może być parentem dla wielu innych komponentów)
  • Albo HoC to jest ten komponent, który przyjmuje inne komponenty przez swoje właściwości i coś z nimi robi.

W obu przypadkach <Consumer/> jest HoC.

0

Ja spotkałem się z taka definicją, że HOC to funkcja, która przyjmuje komponent i zwraca nowy komponent.

0
sajek587 napisał(a):

Ja spotkałem się z taka definicją, że HOC to funkcja, która przyjmuje komponent i zwraca nowy komponent.

A to nie jest "higher-order function"?

Bo funkcja która zwraca komponent, to nie jest komponent. Owszem, funkcja może być komponentem - ale funkcja która zwraca komponent, nie może (bo komponent nie może zwrócić komponentu, bo niby jak?). Więc jak coś, co nie jest komponentem może się nazywać "higher-order component"?

0

Oficjalna dokumentacja tak mówi: https://reactjs.org/docs/higher-order-components.html#:~:text=A%20higher%2Dorder%20component%20(HOC,and%20returns%20a%20new%20component.

"Concretely, a higher-order component is a function that takes a component and returns a new component."

Tu jest dobry przykład:
https://flexiple.com/react/introduction-to-higher-order-components-in-react-by-example/

Ale czy do Consumera przekazywany jest komponent ? Bo w przykładzie wziętym z dokumentacji nie wygląda to tak jakby do Consumera był przekazywany komponent.

<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer>
0
sajek587 napisał(a):

Oficjalna dokumentacja tak mówi: https://reactjs.org/docs/higher-order-components.html#:~:text=A%20higher%2Dorder%20component%20(HOC,and%20returns%20a%20new%20component.

"Concretely, a higher-order component is a function that takes a component and returns a new component."

Tu jest dobry przykład:
https://flexiple.com/react/introduction-to-higher-order-components-in-react-by-example/

Ale czy do Consumera przekazywany jest komponent ? Bo w przykładzie wziętym z dokumentacji nie wygląda to tak jakby do Consumera był przekazywany komponent.

<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer>

I stand corrected.

0
sajek587 napisał(a):

Ale czy do Consumera przekazywany jest komponent ? Bo w przykładzie wziętym z dokumentacji nie wygląda to tak jakby do Consumera był przekazywany komponent.

<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer>

Wszystko się zgadza. Ten kod JSX zostanie przetłumaczony do wywołania funkcji MyContext.Consumer z tym co jest w środku przekazanym jako argument.

0
szatkus1 napisał(a):
sajek587 napisał(a):

Ale czy do Consumera przekazywany jest komponent ? Bo w przykładzie wziętym z dokumentacji nie wygląda to tak jakby do Consumera był przekazywany komponent.

<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer>

Wszystko się zgadza. Ten kod JSX zostanie przetłumaczony do wywołania funkcji MyContext.Consumer z tym co jest w środku przekazanym jako argument.

Czyli Consumer to komponent wyższego rzędu czy nie?

1
sajek587 napisał(a):
szatkus1 napisał(a):
sajek587 napisał(a):

Ale czy do Consumera przekazywany jest komponent ? Bo w przykładzie wziętym z dokumentacji nie wygląda to tak jakby do Consumera był przekazywany komponent.

<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer>

Wszystko się zgadza. Ten kod JSX zostanie przetłumaczony do wywołania funkcji MyContext.Consumer z tym co jest w środku przekazanym jako argument.

Czyli Consumer to komponent wyższego rzędu czy nie?

A co za różnica?

Tzn. do czego Ci ta informacja potrzebna?

0

Po prostu chcę wiedzieć dla siebie.

0
sajek587 napisał(a):

Po prostu chcę wiedzieć dla siebie.

To ja proponuję samemu ziterpretować podesłany link: https://reactjs.org/docs/higher-order-components.html

0

Czytałem ten artykuł wcześniej i nie mogłem określić czy Consumer to komponent wyższego rzędu czy nie.

1
sajek587 napisał(a):

Czytałem ten artykuł wcześniej i nie mogłem określić czy Consumer to komponent wyższego rzędu czy nie.

To czy <Consumer/> jest HoC czy nie, zależy od tego jaką definicję HoC przyjmiesz.

0

ja tu nie widzę HOCa, po prostu masz pewien komponent, który przyjmuje funkcje:
https://reactjs.org/docs/context.html#contextconsumer
ale w tym przypadku funkcja renderująca nie jest chyba traktowana jak komponent Reactowy, tylko jak funkcja.

Chociaż... żeby się dowiedzieć dokładniej, to trzeba by przejrzeć implementację. Tutaj masz implementację createContext, która zwraca context i do którego można się dostać do konsumenta: context.Consumer
https://github.com/facebook/react/blob/0b4f443020af386f2b48c47c074cb504ed672dc8/packages/react/src/ReactContext.js
problem w tym, że jeśli nic mi nie umknęło, to Consumer w ogóle nie przypomina komponentu React, takiego jakie znamy (tj. ani to funkcyjny komponent, ani klasowy).
Consumer wydaje się być czymś takim:

    const Consumer = {
      $$typeof: REACT_CONTEXT_TYPE,
      _context: context,
    };
    // $FlowFixMe: Flow complains about not setting a value, which is intentional here
    Object.defineProperties(Consumer, {
       // tutaj jakieś dodatkowe właściwości

Wygląda na to więc, że Consumer to jakiś specjalny komponent w React, który jest traktowany w specjalny sposób, a o tym, czy jest Consumerem kontekstu decyduje to $$typeof: REACT_CONTEXT_TYPE. Jak to jest w takim razie renderowane/obsługiwane?

Trzeba by zajrzeć do innego pliku, jak się domyślam do tego:
https://github.com/facebook/react/blob/0b4f443020af386f2b48c47c074cb504ed672dc8/packages/react-reconciler/src/ReactFiber.js#L582
tutaj wydaje się być ten REACT_CONTEXT_TYPE obsługiwany:

case REACT_CONTEXT_TYPE:
  // This is a consumer
  fiberTag = ContextConsumer;

A dalej trzeba byłoby zobaczyć, co robi fiberTag i tak dalej.

Oczywiście moje wnioskowanie może być obarczone błędem, bo może źle połączyłem kropki. Anyway, myślę, że ciekawszą rzeczą od zastanawianie się, czy Consumer to HOC, będzie zajrzenie faktycznie pod maskę i zobaczenie, co tam faktycznie jest. To, co mnie teraz zastanawia - to w jaki sposób jest renderowana zawartość tego Consumera? Przecież podajemy do niej funkcję jako children.

Chociaż użyłem na szybko debuggera i wykryło mi, że on renderuje to tutaj:
https://github.com/facebook/react/blob/0fce6bb498357feb4465859912004b2e20fe7084/packages/react-reconciler/src/ReactFiberBeginWork.js#L3542
w funkcji updateContextConsumer

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.