본문 바로가기

React

[React] Router , action, defer()

컴포넌트 파일에 (컴포넌트 내에 X)

 

action 함수를 만든다.

// action 함수도 리액트 라우터에 의해 실행 됨

export async function action({params, request}){
 const data = await request.formData();
 const method = request.method;
 
 const enteredTitle = {
	title:data.get('title'),
    image:data.get('image'),
 
 
 }
 fetch('주소',{
 	method: 'POST',
    headers: {
    	'Content-Type':'application/json'
    },
    body: JSON.stringify(eventData)
 	
 });
 
 if(!response.ok){
 	throw json({message: 'Could not save event.'},{status:500});
 }
 
 return redirect('목표경로지정')
}

컴포넌트 내에는

 

방법 1. 

<form method="post">

</form>

 

 

방법2. 

import {useSubmit} from 'react-router-dom';

function Test(){
	function sampleTest(){
    	const submit = useSubmit();
    	
        // 첫째 인자 : 제출 데이터
        submit(null, {method: 'delete', action:'라우트 주소(같은 라우트일 경우 생략)'})
        
        
    }
	
    return <>
    	코드..
    
    </>

}

 

 

 

 

* 다른 라우터의 action 실행하고자 할 때 

<form method="post" action="다른 라우터 주소">

</form>

 

 

 

App.js

import { RouterProvider, createBrowserRouter } from 'react-router-dom';

import EditEventPage from './pages/EditEvent';
import ErrorPage from './pages/Error';
import EventDetailPage, {
  loader as eventDetailLoader,
  action as deleteEventAction,
} from './pages/EventDetail';
import EventsPage, { loader as eventsLoader } from './pages/Events';
import EventsRootLayout from './pages/EventsRoot';
import HomePage from './pages/Home';
import NewEventPage from './pages/NewEvent';
import RootLayout from './pages/Root';
import { action as manipulateEventAction } from './components/EventForm';
import NewsletterPage, { action as newsletterAction } from './pages/Newsletter';

const router = createBrowserRouter([
  {
    path: '/',
    element: <RootLayout />,
    errorElement: <ErrorPage />,
    children: [
      { index: true, element: <HomePage /> },
      {
        path: 'events',
        element: <EventsRootLayout />,
        children: [
          {
            index: true,
            element: <EventsPage />,
            loader: eventsLoader,
          },
          {
            path: ':eventId',
            id: 'event-detail',
            loader: eventDetailLoader,
            children: [
              {
                index: true,
                element: <EventDetailPage />,
                action: deleteEventAction,
              },
              {
                path: 'edit',
                element: <EditEventPage />,
                action: manipulateEventAction,
              },
            ],
          },
          {
            path: 'new',
            element: <NewEventPage />,
            action: manipulateEventAction,
          },
        ],
      },
      {
        path: 'newsletter',
        element: <NewsletterPage />,
        action: newsletterAction,
      },
    ],
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;

action 함수를 router에 넣어줌

 

 

useFetcher : loader나 액션이 속한 페이지 또는 라우트를 로딩하지 않고 트리거 할 때 사용

 

defer() : 함수로 데이터 가져오는 것을 연기할 때

 

import {useLoaderData, json,defer,Await} from 'react-router-dom';
import {Suspense} from 'react';

function Test(){
	const {events} = useLoaderData();
    
    
    return 
    <Suspense fallback={<p style={{textAlign: 'center'}}>Loading...</p>}>
    	<Await resolve={events}>
    	{(loadedEvents)=><EventList events={loadedEvents}/> }
    	</Await>
	</Suspense>

}


async function loadEvents(){
   const response = await fetch('주소');
   // ... 코드 작성
   const resData = await response.json();
   return resData.events;
}


export function loader(){
	defer({
    	events: loadEvents()
    });

}

- Suspense - 데이터가 도착하길 기다리는 동안 폴백을 보여주는 특정한 상황에서 사용됨

- Await - 값을 기다림 

 

import {useLoaderData, json,defer,Await} from 'react-router-dom';
import {Suspense} from 'react';

function Test(){
	const {events,event} = useRouterLoaderData();
    
    
    return 
       <Suspense fallback={<p style={{textAlign: 'center'}}>Loading...</p>}>
    		<Await resolve={events}>
    		{(loadedEvents)=><EventList events={loadedEvents}/> }
    		</Await>
       </Suspense>
        <Suspense fallback={<p style={{textAlign: 'center'}}>Loading...</p>}>
        	<Await resolve={event}>
    		{(loadedEvent)=><Event events={loadedEvent}/> }
    		</Await>
		</Suspense>

}


async function loadEvents(){
   const response = await fetch('주소');
   // ... 코드 작성
   const resData = await response.json();
   return resData.events;
}

async function loadEvent(){
   const response = await fetch('주소');
   // ... 코드 작성
   const resData = await response.json();
   return resData.event;
}



export async function loader({request, params}){
	const id = params.eventId;
    
	defer({
        // await세부정보가 로딩되기를 기다린 다음에 이 페이지 컴포넌트를 로딩하게됨
        // events가 로딩되면 event가 로딩됨
    	events: await loadEvents(),
        event: loadEvent(),
    });

}

'React' 카테고리의 다른 글

[React] Tanstack 쿼리  (0) 2024.05.10
[React] 인증  (1) 2024.05.02
[React] router loader, useNavigation  (0) 2024.04.24
[React] router  (0) 2024.04.23
[React] Redux  (0) 2024.04.19