博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初学react实现路由跳转_初学者收集的强大的React技巧和窍门
阅读量:2521 次
发布时间:2019-05-11

本文共 12473 字,大约阅读时间需要 41 分钟。

初学react实现路由跳转

This is part of my “React for beginners” series on introducing React, its core features and best practices to follow. More articles are coming!
这是我的“初学者React”系列的一部分,该系列介绍了React,其核心功能和可遵循的最佳实践。 更多文章来了!

|

|

As you can tell from the title of this article, it’s aimed at beginners.

从本文标题可以看出,它是针对初学者的。

Actually, I started to learn React a few months ago. Reading the React documentation, open source projects, and Medium articles has helped me a lot.

实际上,我是几个月前开始学习React的。 阅读React文档,开源项目和Medium文章对我有很大帮助。

Without a doubt, I’m not an expert in React. And so I read a lot about this topic. Also, building a small projects has helped me get to know React better. Along the way, I’ve adopted some best practices — and I want to share with you here. So let’s get started.

毫无疑问,我不是React的专家。 因此,我阅读了很多有关该主题的文章。 此外,构建一个小型项目还帮助我更好地了解了React。 在此过程中,我采用了一些最佳做法-我想在这里与您分享。 因此,让我们开始吧。

命名您的组件 (Name your components)

To figure which component has a bug, it’s important to always give your component a name.

要弄清楚哪个组件存在错误,务必始终为您的组件命名。

Even more so when you begin to use React Router or third party libraries.

在您开始使用React Router或第三方库时,更是如此。

// Avoid thoses notations export default () => {};export default class extends React.Component {};

There is a debate about whether to use a default or named import. Note that a default import doesn’t ensure that the component’s name is consistent in the project. Besides, will be less effective.

关于使用默认导入还是命名导入存在争议。 请注意, 默认导入不能确保组件名称在项目中保持一致。 此外, 将不太有效。

无论您如何公开组件,都应为其命名 (No matter how you expose your component, name it)

You need to define the class name or the variable name (for functional components) that’s hosting the component.

您需要定义托管组件的类名或变量名(对于功能组件)。

React will actually from it in error messages.

React实际上会在错误消息中从中 。

export const Component = () => 

I'm a component

;export default Component;// Define user custom component nameComponent.displayName = 'My Component';

Here’s my last piece of advice about imports (taken from ): If you use ESLint, you should consider setting the following two rules:

这是我有关导入的最后一条建议(从 ):如果使用ESLint,则应考虑设置以下两个规则:

"rules": {    // Check named import exists    "import/named": 2,       // Set to "on" in airbnb preset    "import/prefer-default-export": "off"}

首选功能组件 (Prefer functional components)

If you have many components whose purpose is only to display data, take advantage of the many ways to :

如果您有许多仅用于显示数据的组件,请利用多种方法来 :

class Watch extends React.Component {  render () {    return 
{this.props.hours}:{this.props.minutes}
}}// Equivalent functional componentconst Watch = (props) =>
{props.hours}:{props.minutes}
;

Both snippets define the same Watch component. Yet, the second is way shorter and even drops this to access the props in the JSX template.

这两个片段定义了相同的Watch组件。 然而,第二个是短的方式,甚至降到this来访问模板JSX道具。

用片段替换div (Replace divs with fragments)

Every component must expose a unique root element as a template. To adhere to this rule, the common fix is to wrap the template in a div.

每个组件都必须公开一个唯一的根元素作为模板。 为了遵守此规则,常见的解决方法是将模板包装在div

React 16 brings us a new feature called . Now you can replace those useless divs with React.Fragments.

React 16为我们带来了一个名为的新功能。 现在,您可以将那些无用的div替换为React.Fragment

The output template will be the fragment content without any wrapper.

输出模板将是没有任何包装的片段内容。

const Login = () =>   
;const Login = () =>
;const Login = () => // Short-hand syntax <>;

设置状态时要小心 (Be careful while setting state)

As soon as your React app is dynamic, you have to deal with components’ states.

一旦您的React应用程序是动态的,您就必须处理组件的状态。

Using states seems pretty straightforward. Initialize the state content in the constructor and then call setState to update the state.

使用状态似乎非常简单。 在constructor初始化状态内容,然后调用setState更新状态

For some reason, you may need to use the current state or props values when calling setState to set the next state’s value.

由于某些原因,在调用setState设置下一个状态的值时,可能需要使用当前状态props值。

// Very bad pratice: do not use this.state and this.props in setState !this.setState({ answered: !this.state.answered, answer });// With quite big states: the tempatation becomes bigger // Here keep the current state and add answer propertythis.setState({ ...this.state, answer });

The issue is that React doesn’t ensure this.state and this.props have the value you’re expecting. setState is asynchronous, because state updates are batch to optimize DOM manipulations (see the details in the and this ).

问题在于,React无法确保this.statethis.props具有您所期望的值。 setState是异步的,因为状态更新是批处理的,可以优化DOM操作(请参见和的详细信息)。

// Note the () notation around the object which makes the JS engine// evaluate as an expression and not as the arrow function blockthis.setState((prevState, props)               => ({ ...prevState, answer }));

To prevent corrupted states, you must use setState with the function parameter. It provides proper state and props values.

为了防止损坏状态,必须将setState与function参数一起使用。 它提供适当的状态和道具值。

绑定组件功能 (Binding component functions)

There are many ways to bind an element’s events to its component, and some are not recommended.

有多种方法可以将元素的事件绑定到其组件,但不建议使用某些方法。

The first and legitimate solution appears in the :

第一个合法的解决方案出现在 :

class DatePicker extends React.Component {   handleDateSelected({target}){     // Do stuff   }   render() {        return    } }

It might disappoint you when you find out that it doesn’t work.

当您发现它不起作用时,它可能会让您感到失望。

The reason is that when using JSX, this value is not bound to the component instance. Here are three alternatives to make it work:

原因是使用JSX时, this值未绑定到组件实例。 以下是三种使其可行的选择:

// #1: use an arrow function this.handleDateSelected(event)}/>// OR #2: bind this to the function in component constructorconstructor () {   this.handleDateSelected = this.handleDateSelected.bind(this); }// OR #3: declare the function as a class field (arrow function syntax)handleDateSelected = ({target}) => {   // Do stuff}

Using an arrow function in JSX as in the first example seems appealing at first. But don’t do it. In reality, your arrow function will be and it’ll hurt performance.

首先,像在第一个示例中那样在JSX中使用箭头函数似乎很有吸引力。 但是不要这样做。 实际上,将箭头函数,这会影响性能。

Also, be careful about the last solution. It uses class fields syntax which is only a .

另外,请注意最后的解决方案。 它使用类字段语法,这只是的 。

This means that you have to use to the code. If the syntax is not finally adopted, your code will break.

这意味着您必须使用来代码。 如果最终没有采用语法,则代码将中断。

采用容器模式(即使在Redux中也是如此) (Adopt container pattern (even with Redux))

Last but not the least, the container design pattern. This allows you to follow the principle in the React component.

最后但并非最不重要的是容器设计模式。 这使您可以遵循React组件原则。

export class DatePicker extends React.Component {  state = { currentDate: null };  handleDateSelected = ({target}) =>     this.setState({ currentDate: target.value });  render = () =>      }

A single component handles template rendering and user actions in the same place. Let’s use two components instead:

单个组件可在同一位置处理模板渲染和用户操作。 让我们使用两个组件代替:

const DatePicker = (props) =>           export class DatePickerController extends React.Component {   // ... No changes except render function ...  render = () =>      
;}

Here is the trick. DatePickerContainer handles user interactions and API calls if necessary. Then it renders a DatePicker and supplies props.

这是窍门。 DatePickerContainer在必要时处理用户交互和API调用。 然后,它渲染一个DatePicker并提供道具。

Thanks to this pattern, the container component replaces the presentational component. This functional component becomes useless without props.

由于这种模式,容器组件取代了展示组件。 没有道具,此功能组件将变得无用。

export const DatePickerContainer =  connect(mapStateToProps, mapDispatchToProps)(DatePickerController);

In addition, if you use Redux as the state manager for you app, it also plugs well with this pattern.

此外,如果您将Redux用作应用程序的状态管理器,那么它也可以很好地插入此模式。

The connect function injects props into the component. In our case, it will feed the controller which will forward those props to the component.

connect函数将props注入到组件中。 在我们的例子中,它将提供给控制器,控制器会将这些道具转发到组件。

Thus both components will be able to access to Redux data. Here is the full code for the container design pattern (without Redux or class fields syntax).

因此,这两个组件都将能够访问Redux数据。 这是容器设计模式的完整代码(没有Redux或类字段语法)。

奖励:修复道具钻Kong (Bonus: Fix props drilling)

While writing my learning project for React, I noticed a bad pattern that bothered me with props. On each page, I had a main component that used the store and rendered some nested dumb components.

在为React写我的学习项目时,我注意到一个糟糕的模式使我困扰于道具。 在每个页面上,我都有一个使用商店的主要组件,并呈现了一些嵌套的哑组件。

How can deeply nested dumb components access the main component data ? Actually, they can’t — but you can fix it by:

深度嵌套的哑组件如何访问主组件数据? 实际上,它们不能-但是您可以通过以下方法解决此问题:

  • wrapping the dumb component in a container (it becomes smart)

    将笨拙的组件包装在容器中(变得很聪明)
  • or pass down props from the top component

    或从顶部组件传递道具

The second solution implies that components between the top component and the dumb component will have to pass down props they don’t need.

第二种解决方案意味着顶级组件和哑组件之间的组件将必须传递不需要的道具。

const Page = props => 
; const UserDetails = props =>

User details

// <= No need fullName but pass it down
;const inputStyle = { height: '30px', width: '200px', fontSize: '19px', border: 'none', borderBottom: '1px solid black'};const CustomInput = props => // v Finally use fullName value from Page component ;

The React community has named this issue prop drilling.

React社区已将此问题命名为prop drill

Page is the main component that loads the user details. It is necessary to pass this data through UserDetails to take it to CustomInput.

Page是加载用户详细信息的主要组件。 必须通过UserDetails传递此数据,以将其传递给CustomInput

In this example, the prop only passes through one component which doesn’t need it. But it can be far more if you have reusable components. For example, the Facebook codebase contains a few thousand reusable components!

在此示例中,道具仅穿过一个不需要的组件。 但是,如果您具有可重用的组件,则可能会更多。 例如,Facebook代码库包含数千个可重用组件!

Don’t worry, I’m going to teach you three ways to fix it. The two first methods appear in the : children prop and render prop.

不用担心,我将教您三种修复方法。 前两种方法出现在 : children proprender prop

// #1: Use children propconst UserDetailsWithChildren = props => 

User details (with children)

{props.children /* <= use children */}
;// #2: Render prop patternconst UserDetailsWithRenderProp = props =>

User details (with render prop)

{props.renderFullName() /* <= use passed render function */}
;const Page = () =>
{/* #1: Children prop */}
{/* Defines props.children */}
{/* #2: Render prop pattern */} {/* Remember: passing arrow functions is a bad pratice, make it a method of Page class instead */}
}/>
;

These solutions are pretty similar. I prefer using children, because it works well within the render method. Note that you can also extend those patterns by providing deeper nested components.

这些解决方案非常相似。 我更喜欢使用子级,因为它在render方法中效果很好。 请注意,您还可以通过提供更深层的嵌套组件来扩展这些模式。

const Page = () =>  

The third example uses the experimental context API.

第三个示例使用实验上下文API。

const UserFullNameContext = React.createContext('userFullName');const Page = () => 
{/* Fill context with value */}
;const UserDetailsWithContext = () => // No props to provide

User details (with context)

{/* Get context value */} { fullName =>
}
;

I don’t recommend this method, because it’s using an experimental feature. (And this is why the API recently .) Also, it forces you to create a global variable to store the context, and your component gets an unclear new dependency (the context can contain anything).

我不推荐这种方法,因为它使用的是实验功能。 (这就是API最近原因。)此外,它迫使您创建一个全局变量来存储上下文,并且您的组件会获得不清楚的新依赖关系(上下文可以包含任何内容)。

而已! (That’s it!)

Thanks for reading. I hope you learned some interesting tips about React!

谢谢阅读。 希望您了解了一些关于React的有趣提示!

If you found this article useful, please click on the 👏 button a few times to make others find the article and to show your support! 👊

如果您觉得这篇文章很有用,请单击 几次make按钮,以使其他人找到该文章并表示支持! 👊

Don’t forget to follow me to get notified of my upcoming articles 🙏

不要忘记关注我,以获取有关我即将发表的文章的通知 🙏

This is part of my “React for beginners” series on introducing React, its core features and best practices to follow.
这是我的“初学者React”系列的一部分,该系列介绍了React,其核心功能和可遵循的最佳实践。

|

|

➥JavaScript (➥ JavaScript)

  • ?

➥提示与技巧 (➥ Tips & tricks)

翻译自:

初学react实现路由跳转

转载地址:http://pdwzd.baihongyu.com/

你可能感兴趣的文章
MTK android 设置里 "关于手机" 信息参数修改
查看>>
单变量微积分笔记6——线性近似和二阶近似
查看>>
补几天前的读书笔记
查看>>
HDU 1829/POJ 2492 A Bug's Life
查看>>
CKplayer:视频推荐和分享插件设置
查看>>
CentOS系统将UTC时间修改为CST时间
查看>>
redis常见面试题
查看>>
导航控制器的出栈
查看>>
玩转CSS3,嗨翻WEB前端,CSS3伪类元素详解/深入浅出[原创][5+3时代]
查看>>
iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置
查看>>
Delphi消息小记
查看>>
JVM介绍
查看>>
将PHP数组输出为HTML表格
查看>>
经典排序算法回顾:选择排序,快速排序
查看>>
BZOJ2213 [Poi2011]Difference 【乱搞】
查看>>
一道关于员工与部门查询的SQL笔试题
查看>>
Canvas基础
查看>>
[Hive - LanguageManual] Alter Table/Partition/Column
查看>>
可持久化数组
查看>>
去除IDEA报黄色/灰色的重复代码的下划波浪线
查看>>