初学react实现路由跳转
React大部分都是基于纯Javascript构建的。 在这里,您将了解10个Javascript概念,这些概念将帮助您编写更好的React代码。
Let和const变量
let用于创建后需要重新分配的变量。
Const用于不需要重新分配或更改的变量。
这两个变量都限制在包围它们的花括号的范围内。 (它们是块作用域的)
当您尝试重新分配const时会发生什么?
const newUser = true ;
newUser = false ; // TypeError: Assignment to constant variable.
在React中
let和const是声明变量的首选方式,因为它们的行为是可预测的。
结合箭头功能声明组件时,也建议使用const ,因为组件保持不变。
const Header = () => {
// Local variable declared with const
const username = "Bob" ;
return < Header > Welcome back, {username}!;
}
模式字符串
用JavaScript
模板字符串比Java语言中使用单引号或双引号获得的基本String类型动态得多。 使用它们更容易将值插值并粘贴到字符串中。
使用语法$ {}在Javascript中插入有效的表达式就足够了。 连接和合并字符串不需要“ +”运算符,因为不需要使用换行符(\ n)或回车符(\ r)创建新的字符串,所以编写String类型的多行对象更加容易。 。
另外,可以在模式字符串中使用封闭的引号(单引号和双引号),而不必担心错误。
const username = "Fred" ;
// Code in which strings are concatenated using "+" is difficult to read
const greeting = "Hi " + username + ", how are you?" ;
// Template strings (``) are much easier to write and read
const username = "Anna" ;
// Dynamic values are inserted using the expression $ {}
const greeting = `Hi ${username} , how are you?` ;
在React Template中,字符串用于创建String类的复杂对象,以及根据条件动态计算元素的样式。 您可以插入变量值,运算符,函数调用等。
function UserCard ( { id, name } ) {
// check user id ...
const isOddUser = id % 2 !== 0 ;
// Odds get a dark background
return < div className = {idOddUser ? ' dark-bg ' : ''}> {name} </ div > }
<UserCard id={ 1 } name= "Bob" /> // displays UserCard with a dark background
箭头功能
在JavaScript中
速写语法可以与箭头功能一起使用。 这使整个代码更短。 您可以使用大箭头(=>)替换return关键字(如果没有花括号,则默认情况下返回),并且可以将函数主体(弯括号)替换为大箭头。
通过this关键字使用对象和类更容易。 您也可以删除单个参数的括号。
// Standard function
function capitalize ( word ) {
return word.toUpperCase();
}
// Arrow function
const capitalize = ( word ) => {
return word.toUpperCase();
}
// Use all the features of the arrow function
const capitalize = word => word.toUpperCase();
在React中
如果可以使用JavaScript创建标准函数,则可以创建箭头函数。 通常,第二个选项更可取,因为语法更简单。
大多数情况下,箭头函数用于创建组件以及用于高阶数组方法,例如.map()或.filter()。
const UserList = ( { users } ) => {
return (
{users.map( ( user, index ) => ( ))}
);
}
数组方法.map()、. filter()、. reduce()等。
用JavaScript
像for循环一样,map,filter和reduce数组方法允许您迭代数组的元素:
- .map()-允许您转换数组的每个元素;
- .filter()-创建一个新数组,其中包含所有通过函数指定测试的元素;
- .reduce()-允许您根据我们的需求转换整个数组(即使是不同的数据类型)。
这些方法比for循环更短,更易于阅读。 通过结合使用这些方法和箭头功能,可以进一步减少代码。
// Purpose: convert the users array to usernames array
const users = [
{ name : "Bob" , id : 1 },
{ name : "Jane" , id : 2 },
{ name : "Fred" , id : 3 }
];
const usernames = [];
// For loop
for ( let i = 0 ; i < users.length; i++) {
usernames[i] = users[i]
}
usernames; // ["Bob", "Jane", "Fred"]
// .map() - concise + readable
const usernames = users.map( user => user.username);
usernames; // ["Bob", "Jane", "Fred"]
在React中
.map( ) 、. filter()、. reduce ()方法可用于转换数据。 它们通常用于使用.JSX动态显示元素和组件,因为可以将这些方法链接在一起进行连续转换。
function UserList () {
const users = [
{ name : "Bob" , id : 1 },
{ name : "Jane" , id : 2 },
{ name : "Fred" , id : 3 }
];
// Drop the user with id = 2 and then distribute the entries and display the usernames
return (
< ul >
{users
.filter(user => user.id !== 2) <
.map ( user => <li key={id}>{user.name}</li> )
}
</ ul >
);
};
破坏性分配
用JavaScript
破坏性分配使您可以将数组或对象解压缩为变量。 这是一个方便的概念,因为当我们要使用整个对象时,不需要引用整个对象。
通过解构,我们可以从对象中提取所需的值,并为此值创建一个自变量。 当我们只需要其值之一时,就可以使代码更整洁,而无需引用该对象。
const user = {
name : "Reed" ,
username : "ReedBarger" ,
email : "reed@gmail.com" ,
details : {
title : "Programmer"
}
};
// Access to the object without destructuring
console .log( ` ${user.name} , ${user.email} ` ); // logs: Reed, reed@gmail.com
// Restructure the object to reduce repetition
const { name, email } = user;
console .log( ` ${name} , ${email} ` ); // logs: Reed, reed@gmail.com
// Restructuring an object with a nested object "details"
const { username, details : { title } } = user;
console .log( ` ${username} , ${title} ` ); // logs: ReedBarger, Programmer
在React中
最常见的是,破坏性分配用于获取对象的单个属性的值。 如果仅将对象的一个属性传递给给定的组件,则不需要所有其他属性。 除了引用属性外,我们还可以对它们进行结构分解并将一个变量传递给组件。
function App () {
return (
< div >
<h1>All Users</h1>
<UserList users={["Bob", "Jane", "Fred"]} />
</div>
);
}
function UserList ( { users } ) {
return (
< ul >
{users.map((user, index) => (
<li key={index}>{user}</li>
))}
</ ul >
);
}
默认选项
在JavaScript中
默认参数对于处理不带参数的函数传递的事件很有用。 它们还将有助于避免错误并使代码更可预测。
// No default parameters
function sayHi ( name ) {
return "Hi" + name;
}
sayHi(); // "Hi undefined"
// With default parameters
function sayHi ( name = 'Bob' ) {
return "Hi" + name;
}
sayHi(); // "Hi Bob"
// With default parameters and arrow function
const sayHi = ( name = 'Jane' ) => "Hi" + name;
sayHi(); // "Hi Jane"
在React中
定义属性时,通常使用默认设置。 在下面的示例中,我们使用破坏性分配从对象的属性中获取“用户名”参数。 尽管未传递该属性,但默认值设置为“ guest”,并且该组件仍然有效。
const Header = ( { username = "guest" } ) => {
return < header > Welcome, {username}! </ header > ;
}
<Header /> // prints: Welcome, guest!
传播语法(三个点-...)
用JavaScript
传播语法使您可以扩展对象(它们的键值对)和数组以获取新对象。 此语法仅在创建新对象或数组时有效。
传播语法非常适合将旧对象的属性组合到新对象中。 当对象或数组扩展以创建新的对象或数组时,将显示一个临时副本。
// Combine empty default data with user data from the subscription form
// using the operator operator
const user = {
name : "" ,
email : "" ,
phoneNumber : "" ,
};
const newUser = {
name : "ReedBarger" ,
email : "reed@gmail.com" ,
};
//The last object, when expanding, replaces the value of the same properties of the previous object with its own
//
const mergedUser = { ...user, ...newUser };
mergedUser; // { name: "ReedBarger", email: "reed@gmail.com", phoneNumber: "" };
在React中
传播语法非常适合动态创建新对象和数组。 它通常在React库(如Redux)中用于更可预测的数据更改。
另外,在React中,这种技术可以用于将对象数据作为一组属性传输而无需依次访问它们:为此,我们可以将对象扩展为组件,因为我们将获得一组属性的对象。
function App () {
const name = {
first : "Reed" ,
last : "Barger"
};
return (
< div >
{/*
<UserGreeting
first={name.first}
last={name.last}
/>
*/}
<UserGreeting {...name} />
</div>
);
}
function User({ first, last }) {
return (
<p>
Hi, {first} {last}
</p>
);
}
简短的条件语句
用JavaScript
JavaScript具有用于编写条件if-else语句(三元操作)的缩写形式。 与if-else不同,三元运算是表达式。 这为您提供了极大的灵活性,使您可以像使用其他任何表达式一样使用它们(对于模式字符串,例如$ {})。
三元运算并不总是比if-else语句更好。 例如,当处理多个条件时,前者将不可读。
let age = 26 ;
let greeting;
// Without the if-else operator in such cases, you can do. Here we just
// assign the value to the variable depending on the condition
if (age > 18 ) {
greeting = "Hello, fellow adult" ;
} else {
greeting = "Hey kiddo" ;
}
// Ternary operations do the same thing, but much shorter
const greeting = age > 18 ? "Hello, fellow adult" : "Hey kiddo" ;
greeting; // 'Hello, fellow adult';
在React中
如果条件为true,则可以通过JSX输出,如果条件为false,则可以输出另一结果,而编写代码的时间比通过if-else短得多。
如果仅在条件为真时才需要输出结果,则可以使用&&运算符。
const Navbar = () => {
const isAuth = true ;
return (
< div >
// For authorized users, shows a list of links, for others - an authorization screen
{isAuth ? <AuthLinks /> : <Login /> }
// Show profile to authorized users only
{isAuth && <UserProfile/> }
</ div >
);
}
ES模块
用JavaScript
使用ES模块,可以很方便地在应用程序文件之间分发代码。 我们将要传输的内容导出到应用程序的其他文件(主要是变量和函数)中,然后在需要时导入它们。
您可以使用大括号(和关键字导出/导入)执行多个导出/导入,或者不使用方括号(使用关键字导出默认和导入)执行多个导出/导入。
这种方法使您可以使代码模块化。 我们可以在需要的地方编写代码,而无需将所有内容收集到一个大文件中。 下面的示例显示如何从app.js中的单独文件调用getLocalTime函数。
// utils/getLocalTime.js
const getLocalTime = () => new Date ().toLocaleTimeString();
export default getLocalTime;
// app.js
import getLocalTime from './utils/getLocalTime.js'
const App = () => {
return (
< div >
<header>The time is {getLocalTime()}</header>
...
</ div >
);
}
在React中
您可以导出和导入几乎所有内容,不仅是JS,而且还可以导出CSS,图像文件等。
在React中,导入JavaScript时通常不需要添加文件扩展名。 仅当将其他文件类型导入JS时才需要扩展名。
// App.js
const App = () =>
hello world!
// styles.css
html, body {
margin : 0 ;
padding: 0 ;
}
h1 {
color : cornflowerblue;
}
// index.js
import React from 'react' ;
import './styles.css'
import ReactDOM from "react-dom" ;
import App from "./App" ;
const rootElement = document .getElementById( "root" );
ReactDOM.render( < App /> , rootElement);
承诺+异步/等待
用JavaScript
您可以无限期延迟JavaScript中某些代码部分的执行(例如setTimeout(),侦听器事件或带有访存API的网络请求)。
承诺是使异步JS代码可预测的一种方法。 它们有助于解析使用异步创建的代码。 使用.then()回调函数处理成功执行的代码,使用.catch()函数处理错误;
async / await是用于处理promise的改进语法,可使异步代码看起来是同步的。
// Asynchronous code; 'done' is logged after position data, although 'done' is assumed
// execute in code later
navigator.geolocation.getCurrentPosition( position => {
console .log(position);
}, error => {
console .error(error);
});
console .log( "done" );
// Asynchronous code processed after the promise; we get the desired result - position data
// logged, then logged 'done'
const promise = new Promise ( ( resolve, reject ) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
promise
.then( position => console .log(position))
.catch( error => console .error(error))
.finally( () => console .log( 'done' ));
// Asynchronous code with async / await looks like a synchronous, most readable way
// work with promises
async function getPosition () {
// async / await only works in functions (for now)
const result = await new Promise ( ( resolve, reject ) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
const position = await result;
console .log(position);
console .log( 'done' );
}
getPosition();
在React中
承诺和异步/等待用于创建网络请求,例如API调用。
诸如fetch API或axios之类的库将Promise应用于可能无限期完成的请求。 相似库中的Promise和async / await也用于形成网络请求:
// Get data through the API using the basic syntax of the promise (pay attention to arrow functions)
window .fetch( 'http://jsonplaceholder.typicode.com/posts' )
.then( response => response.json())
.then( data => console .log(data));
// Get the same data through the API using async / await
async function getPostData () {
const response = await window .fetch( 'http://jsonplaceholder.typicode.com/posts' )
// We need to allow two promises using await to get the resulting data
const data = await response.json();
console .log(data);
}
getPostData();
实践使完美。 经过长时间的实践,我们的工作将变得自然,熟练,敏捷,稳定。
本文的主要目的是帮助您编写更好,更高效的代码。 如果您有任何疑问,请与我联系,我们将很乐意回答您的所有问题。
一切顺利-丹尼森·阿里亚斯(Dannison Arias)
初学react实现路由跳转