Renderowanie statusu poza elementem div

Renderowanie statusu poza elementem div

Wątek przeniesiony 2024-06-04 16:39 z JavaScript przez Riddle.

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Witam

W ramach treningu Portali w React postanowiłem rozwiązać taki problem jak renderowanie tablicy z obiektem poza elementem div poprzez utworzenie Portalu aczkolwiek sterowane przyciskiem. Sama tablica z obiektem była by przypisana do useState.
Wymyśliłem to więc w taki sposób:

  1. Utworzenie tablicy obiektów/stringow w useState
  2. Renderowanie status w div
  3. Renderowanie statusu poprzez Portal po za div

Na razie pomysł nie wychodzi, być może droga nie ta.

Kopiuj
import { createPortal } from 'react-dom';
import { useState } from 'react';
import ReactDOM  from 'react-dom/client';

const listOfShoes = [
    {typeOfShoes : "sandals",
    brand : "Laoke",
    price : "100",
    currency : "punds"}
];
        
export function RenderArrObject(){
    var [arrOfObjects, setArrOfObjects] = useState(listOfShoes);
    
    function handleButton(){

        return(
            <ul>
                {arrOfObjects.map( content => (
            <li key={content.typeOfShoes}>
                {content.typeOfShoes}
                {content.brand}
                {content.price}
            </li>
                ))}
            </ul>
        )
        }

return(
        <div>
            <button onClick={handleButton}>Generate</button>
</div>
        
    )
}

const execute = ReactDOM.createRoot(document.getElementById('root'));
execute.render(<RenderArrObject />);

dzek69
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Rzeszów
2

A gdzie tu jakiś portal jest?

Ogólnie czytałem to kilka razy i dalej nie mogę zrozumieć co w ogóle chcesz osiągnąć.

Pokaż jakąś stronę która robi to samo, albo narysuj w paincie.

Na pewno ten callback, który zwraca elementy JSX (z którymi nic się nie wydarzy) zalatuje mi programowaniem imperatywnym. Wydaje mi się, że nie łapiesz idei Reacta jeszcze, a już bierzesz się za rzeczy zaawansowane.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 168
0

"Wydaje mi się, że nie łapiesz idei Reacta jeszcze"
Zgadzam się z przedmówcą.

arrOfObjects - po prostu zrenderuj tabele/liste z zawartością.
Przycisk generate jest w zasadzie zbędny. handleButton nie powinien zwracać html'a

Jeżeli bardzo chcesz przycisk generate, to możesz spróbować.

Kopiuj
var [arrOfObjects, setArrOfObjects] = useState([])  // inicjalizacja pusta lista


function handleButton(){
  setArrOfObjects(listOfShoes)  // zmienisz stan wiec component sie przerenderuje

}

return(<>
        <div>
            <button onClick={handleButton}>Generate</button>
      </div>
      <ul>... dane co chcesz zaprezentować </ul>
</>)
D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Podzieliłem ten problem na mniejsze dlatego wypisałem kroki na samej górze Najpierw chce zrenderować listę w div, potem utworzyć portal do aby po użyciu przycisku lista wyświetliła się w body dokumentu. Portale nie są łatwe, ale hook typu useState nie jest aż tak skomplikowany. Chciałem zobaczyć czy da się połączyć te dwie rzeczy. Równie dobrze można by próbować z obiektem state. Co nieco Reacta już przepracowałem więc sądzę, że taki ,,laik" ze mnie nie jest. Pytanie jaki mielibyście pomysł na rozwiązanie tego problemu.

Renderujemy obiekt w paragrafie, same dane pobieramy ze statusu zarzadzając tym z poziomu przycisku.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 168
0

https://react.dev/reference/react-dom/createPortal

Kopiuj
import { createPortal } from 'react-dom';

export default function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}

Zamiast paragrafu miej swój komponent który prezentuje dane.
use state do zapisania stanu czy przycisk został kliknięty
Na podstawie stanu można warunkowo tworzyć część create portal.

Kopiuj
      {warunek && createPortal(   // jeśli warunek/boolean zwróci false to createPortal nie będzie wykonywane/renderowane
        <p>This child is placed in the document body.</p>,
        document.body
      )}

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Po prawie 3h prób szybkiej edukacji z warunków udało się skonstruować coś takiego co nawet spełnia zasady czystego kodu. Nie jestem pewien czy krsp miał to na myśli. Prościej się chyba nie da tego ująć :

Kopiuj
import {useState} from 'react';
import ReactDOM  from 'react-dom/client';
import { createPortal } from 'react-dom';

export function CheckTheState(){

    const[componentState, setComponentState] = useState("State of component");
    const[btnState, setState] = useState(false);


    function checkBtnState(){
        setState(true);
        
        <RenderOutsideComponent />
    }

    function ComponentToTeleport(){

        return(
            <p>{componentState}</p>
            
        )
    }

    function RenderOutsideComponent(){

        if(btnState)
        {
            return(
                <div>
                    
                    {btnState && createPortal(
                    <ComponentToTeleport />, document.body)
                    }
                    
                </div>
            )
        }
    }

    return(
        <div>
            <button onClick={checkBtnState}>Action</button>
            <RenderOutsideComponent />
        </div>
        
    )
}

const execute = ReactDOM.createRoot(document.getElementById('root'));
execute.render(<CheckTheState />);

Co do nauki to co na razie wyznaje zasadę. Nie znasz pewnego elementu kodu daj sobie ze 3 dni i pobaw się trochę zagadnieniem aczkolwiek czasem czlowiek albo wymyśli problem zbyt skomplikowany albo zbyt odejdzie od koncepcji zagadnienia. Dokumentacja daje trochę dobrych przykładów które można przerobić, ale tutaj istotna kreatywność.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 168
0

To miałem na myśli.
Bardziej rzucące się w oczy rzeczy:

Kopiuj
    function checkBtnState(){
        setState(true);
        
        <RenderOutsideComponent />
    }

Na podstawie tego kodu, są pytania odnośnie wyczucia użycia reacta.
RenderOutsideComponent jest totalnie zbędny i nic nie robi. Teraze tez nazwa funkcji jest myląca bo ona nic nie sprawdza. Ona ustawia stan żeby na jego podstawie wyrenderować z użyciem create portal. Jesze bym dodał możliwość zmieniania z powrotem tej flagi (toggle).

Kopiuj
    function checkBtnState(){
        setState(prevState => !prevState);
    }

W RenderOutsideComponent if(btnState) jest zbędny (duplikuje sprawdzenie)

Kopiuj
    function RenderOutsideComponent(){
            return(
                <div>
                    {btnState && createPortal(
                        <ComponentToTeleport />, document.body)
                    }

                </div>
            )
    }

Ja osobiście nie zadnieżdżam implementacji komponentów i preferuje coś w stylu:

Kopiuj
import {useState} from 'react';
import ReactDOM from 'react-dom/client';
import {createPortal} from 'react-dom';

export function CheckTheState() {

    const [btnState, setState] = useState(false);

    function checkBtnState() {
        setState(prevState => !prevState);
    }

    return (
        <div>
            <button onClick={checkBtnState}>Action</button>
            <RenderOutsideComponent btnState={btnState}/>
        </div>

    )
}

function RenderOutsideComponent(props) {
    const btnState = props.btnState;

    return (
        <div>
            {btnState && createPortal(
                <ComponentToTeleport/>, document.body)
            }
        </div>
    )
}

function ComponentToTeleport() {
    const [componentState, setComponentState] = useState("State of component");

    return (
        <p>{componentState}</p>

    )
}


const execute = ReactDOM.createRoot(document.getElementById('root'));
execute.render(<CheckTheState/>);

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.