首页 > 其他分享 >react-router-dom(v6)快速上手

react-router-dom(v6)快速上手

时间:2022-10-19 00:46:27浏览次数:66  
标签:const data react v6 action router navigation

本篇笔记跟随官方教程而写,把其中连续的步骤碎片化,方便以后忘记的时候直接调用, 其中包含了对其他小问题的拓展。

创建路由(quick-start)

npm install react-router-dom

在React项目中使用,一般在最上层页面中配置,比如index.js或者App.js, etc

import {
	createBrowserRouter,
	ProviderRouter,
	Route
}

...

const render = createBrowserRouter([
	{
		//index: true --to set as the default page
		path: '/',
		element: <APage/>,
		errorElement: <ErrPage/>,
		children: {
			...	
		}
	}
])

ReactDOM.createRoot(document.querySelector('#root')).render(
	<React.StrictMode>
		<ProviderRouter router={router}/>
	</React.StrictMode>
)

使用loader和action

|- src
	|- Person.js
	|- Main.js
|- index.js

以一个根据数据动态加载页面为例,假设我们有以下数据

[
	{
		id: 2K39pAxd,
		name: 'tom',
		career: 'doctor'
	},
	...
]

//Person.js
...

export async function getData() {
	const data = await localforage.getItem('data');
	return data ? data : [] ;
}

export async function createDate() {
	const data = await getData();
	let item = generateData();//function that you use to generate a data item
	data.unshift(item);
	localforage.setIitem('data', data);
	return data;
}

我们在上面的js中定义一系列的数据和API,接下来就需要将其应用到路由中去
我们需要根据上面的数据生成一个person page。

这里用到loader和action,先看是怎么应用的再进行说明。

//Main.js
import { getData, createData } from './Person'

export async function loader( {request, params} ) {
	const Data = await getData();
	return { Data };
}

export async function action( {request, params} ) {
	await createData();
}

之后配置到路由中

(在上面的loader和action中,有两个参数,一个是request,就是form表单发送的产生的request对象,详细方法和属性看这里,params即路由中携带的参数)

import {loader, action} from './src/Main'

...
const router = createBrowserRouter([
	{
		path: '/',
		element: <Main />,
		loader: loader,
		action: action
		children: {
			page: '/pages/:personId',
			element: <personPage />
		}
	}
])

ok,从这里我们还没有看Main组件中受到loader的数据是怎么获取的,以及action要怎么触发,什么时候触发。接下来就分开进行说明

loader数据获取

在之前的coding中,通过loader,在Main组件挂载的时候(函数式组件),就向其传输了一块数据。react-router-dom提供了一个hook来获取这个数据

const data = useLoaderData();

action的机制

在上面的代码中,我们向路由配置了action,也编写了其实现函数,但唯独没有提到action的调用。
action在路由收到一个除Get外的提交时触发。

在传统的html中使用<form>来构建一个表格,然后表格提交的时候,会根据其内容提交一次http请求给服务器,但这里是router,显然不需要这样的结果。在之前的学习中,一般使用e.preventDefault()来进行处理,不过react-router-dom提供了另一个组件<Form>来解决这个问题

//Main.js
...
<Form method='post'>
	<button type='submit'>trigger the action</button>
</Form>

(但form中没有submit的input时,会默认以一个button作为提交)

在官方文档中,还提到了一个hook叫useNavigation, 这应该是新版本的特性,因为在bing上搜索都没有对它的讨论。

import { useNavigation } from "react-router-dom";

function SomeComponent() {
  const navigation = useNavigation();
  navigation.state;
  navigation.location;
  navigation.formData;
  navigation.formAction;
  navigation.formMethod;
}

在页面发生跳转,比如点击一个<Link/>或者提交发送一个表单数据,通过这个hook就可以对数据进行对应的处理。
比如

// Is this just a normal load?
let isNormalLoad =
  navigation.state === "loading" &&
  navigation.formData == null;

// Are we reloading after an action?
let isReloading =
  navigation.state === "loading" &&
  navigation.formData != null &&
  navigation.formAction === navigation.location.pathname;

// Are we redirecting after an action?
let isRedirecting =
  navigation.state === "loading" &&
  navigation.formData != null &&
  navigation.formAction !== navigation.location.pathname;

重定向到一个页面

在react-route-dom中,函数中重定向有下面几种方法(笔者目前所知道)

  1. action结束后进行跳转
async function action() {
	return redirect('/');
}
  1. useSunmit
import { useSubmit } from 'react-router-dom';
...
	const submit = useSubmit();

	submit(data, {
		method:
		action:
		replace:
	})
...

官方给出了一个用户超时登出的例子

import { useSubmit, useLocation } from "react-router-dom";
import { useEffect } from "react";

function AdminPage() {
  useSessionTimeout();
  return <div>{/* ... */}</div>;
}

function useSessionTimeout() {
  const submit = useSubmit();
  const location = useLocation();

  useEffect(() => {
    const timer = setTimeout(() => {
      submit(null, { method: "post", action: "/logout" });
    }, 5 * 60_000);

    return () => clearTimeout(timer);
  }, [submit, location]);
}
  1. useNavigate
    详细请参考useNavigate
import {useNavigate} from 'react-route-dom';

function APage() {
	const navigate = useNavigate();
	return (
		<>
			<button onClick={() => {
				navigate(-1);
			}}>return to last page</button>
		</>	
	);
}

useFetcher

doc
首先介绍一个概念:
Optimistic UI is a pattern that you can use to simulate the results of a mutation and update the UI even before receiving a response from the server
也就是一种在服务端返回之前就得到对应结果。
useFecher()返回这样一个对象:

import { useFetcher } from "react-router-dom";

function SomeComponent() {
  const fetcher = useFetcher();

  // call submit or load in a useEffect
  React.useEffect(() => {
    fetcher.submit(data, options);
    fetcher.load(href);
  }, [fetcher]);

  // build your UI with these properties
  fetcher.state;
  fetcher.formData;
  fetcher.formMethod;
  fetcher.formAction;
  fetcher.data;

  // render a form that doesn't cause navigation
  return <fetcher.Form />;
}

看起来和useNavigation的结果一样。但是区别在于,useFetch会绕过navigate,直接触发对应的loaderaction
所以通过fetcher.formData,可以在不触发navigate的情况下就可以更新数据,UI,以及其他的操作。

标签:const,data,react,v6,action,router,navigation
From: https://www.cnblogs.com/paprika2/p/16804761.html

相关文章

  • 2022-10-19 react解析富文本
    <divdangerouslySetInnerHTML={{__html:values.content}}></div>dangerouslySetInnerHTML是react标签的一个属性,后面的__html跟返回的富文本数据。注:使用innerHTML......
  • Vue 插件:VueRouter
    VueRouter是一个Vue插件,用于实现SPA(singlepagewebapplication)应用。SPA(singlepagewebapplication)应用,即单页面应用。整个应用只有一个.html文件,通常命名为......
  • 三阶段 vue 路由 $route 和 $router 的区别
    1.这是vue-router提供给我们的实例实例的两个属性(api)2.$route是路由对象,一般是获取动态参数|querythis.$route.params.idthis./$route.title ......
  • react hook
    为什么react的函数组件每次渲染执行两次?刻意为之?这不是一个bug。在严格模式下也会有同样的行为。我们有意在开发中加倍调用渲染阶段生命周期(和使用Hooks的功能组件),以帮......
  • ipv4/ipv6正则校验
    functionis_ipv4(str){ varreg=/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d).){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)$/; returnreg.test(str);}functionis_ipv6(str......
  • vue3实战-完全掌握ref、reactive
    知道大家使用Vue3的时候有没有这样的疑惑,“ref、rective都能创建一个响应式对象,我该如何选择?”,“为什么响应式对象解构之后就失去了响应式?应该如何处理?”今天咱们就来......
  • Spring Reactor 项目核心库
    ReactorCoreNon-Blocking​​ReactiveStreams​​​FoundationfortheJVMbothimplementinga​​ReactiveExtensions​​inspiredAPIandefficienteventstre......
  • Nowa 极简教程:立即上手 webpack & react 开发生态环境
    Nowa省去了用户研究打包,开发,模拟数据等N项变态又无聊的工作。用户可以直接上手写业务代码,不用考虑如何压缩合并代码,如何热加载,如何代理资源等等,如何配置国际化功能等等。......
  • React组件通信
    react因为组件化,使得组件间通信十分的重要。本文就来简单介绍一些常见的react组件间传递的内容。我将归纳为以下几种关系来详述:父组件与子组件之间,子组件与父组件之间,发......
  • 一段探索React自建内部构造的旅程
    一段探索React自建内部构造的旅程在先前的文章里我们涵盖了​​React基本原理​​​和​​如何构建更加复杂的交互组件​​。此篇文章我们将会继续探索React组件的特性,特......