react和react2
by Harsh Makadia
通过苛刻马卡迪亚
为什么React16是React开发人员的福气 (Why React16 is a blessing to React developers)
Just like how people are excited about updating their mobile apps and OS, developers should also be excited to update their frameworks. The new version of the different frameworks come with new features and tricks out of the box.
就像人们对更新其移动应用程序和操作系统感到兴奋一样,开发人员也应该对更新其框架感到兴奋。 不同框架的新版本具有开箱即用的新功能和技巧。
Below are some of the good features you should consider when migrating your existing app to React 16 from React 15.
以下是将现有应用程序从React 15迁移到React 16时应考虑的一些良好功能。
Time to say Goodbye React15 ?
是时候说再见React15了?
错误处理 (Error Handling)
React 16 introduces the new concept of an error boundary.
React 16引入了错误边界的新概念。
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree. They log those errors, and display a fallback UI instead of the crashed component tree. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.
错误边界是React组件,可在其子组件树的任何位置捕获JavaScript错误。 他们记录这些错误,并显示后备UI而不是崩溃的组件树。 错误边界会在渲染期间,生命周期方法以及它们下面的整个树的构造函数中捕获错误。
A class component becomes an error boundary if it defines a new lifecycle method called componentDidCatch(error, info)
:
如果类组件定义了一个称为componentDidCatch(error, info)
新生命周期方法,则它将成为错误边界:
Then you can use it as a regular component.
然后,您可以将其用作常规组件。
<ErrorBoundary> <MyWidget /></ErrorBoundary>
The componentDidCatch()
method works like a JavaScript catch {}
block, but for components. Only class components can be error boundaries. In practice, most of the time you’ll want to declare an error boundary component once. Then you’ll use it throughout your application.
componentDidCatch()
方法的工作方式类似于JavaScript catch {}
块,但适用于组件。 只有类组件才能成为错误边界。 实际上,大多数情况下,您只需要声明一次错误边界组件。 然后,您将在整个应用程序中使用它。
Note that error boundaries only catch errors in the components below them in the tree. An error boundary can’t catch an error within itself. If an error boundary fails trying to render the error message, the error will propagate to the closest error boundary above it. This, too, is similar to how catch {}
block works in JavaScript.
请注意, 错误边界仅捕获树中位于其下方的组件中的错误 。 错误边界本身无法捕获错误。 如果错误边界在尝试呈现错误消息时失败,则错误将传播到其上方最近的错误边界。 这也类似于catch {}
块在JavaScript中的工作方式。
Check out the live demo:
查看现场演示:
For more information on error handling, head here.
有关错误处理的更多信息,请访问此处 。
新的渲染返回类型:片段和字符串 (New render return types: fragments and strings)
Get rid of wrapping the component in a div while rendering.
消除在渲染时将组件包装在div中的麻烦。
You can now return an array of elements from a component’s render
method. Like with other arrays, you’ll need to add a key to each element to avoid the key warning:
现在,您可以从组件的render
方法返回一个元素数组。 与其他数组一样,您需要向每个元素添加一个键,以避免出现键警告:
render() { // No need to wrap list items in an extra element! return [ // Don't forget the keys :) <li key="A">First item</li>, <li key="B">Second item</li>, <li key="C">Third item</li>, ];}
Starting with React 16.2.0, it has support for a special fragment syntax to JSX that doesn’t require keys.
从React 16.2.0开始 ,它支持JSX不需要密钥的特殊片段语法。
Support for returning strings :
支持返回字符串:
render() { return 'Look ma, no spans!';}
门户网站 (Portals)
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
门户网站提供了一种一流的方法来将子级呈现到父组件的DOM层次结构之外的DOM节点中。
ReactDOM.createPortal(child, container)
The first argument (child
) is any renderable React child, such as an element, string, or fragment. The second argument (container
) is a DOM element.
第一个参数( child
)是任何可渲染的React child ,例如元素,字符串或片段。 第二个参数( container
)是DOM元素。
如何使用它 (How to use it)
When you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node:
当您从组件的render方法返回一个元素时,该元素将作为最近的父节点的子节点安装到DOM中:
render() { // React mounts a new div and renders the children into it return ( <div> {this.props.children} </div> );}
Sometimes it’s useful to insert a child into a different location in the DOM:
有时将子级插入DOM中的其他位置很有用:
render() { // React does *not* create a new div. It renders the children into `domNode`. // `domNode` is any valid DOM node, regardless of its location in the DOM. return ReactDOM.createPortal( this.props.children, domNode );}
A typical use case for portals is when a parent component has an overflow: hidden
or z-index
style, but you need the child to visually “break out” of its container. For example, dialogs, hovercards, and tooltips.
门户的典型用例是父组件出现overflow: hidden
或z-index
样式,但是您需要子组件以可视方式“脱离”其容器。 例如,对话框,悬浮卡和工具提示。
自定义DOM属性 (Custom DOM Attribute)
React15 used to ignore any unknown DOM attributes. It would just skip them since React didn’t recognize it.
React15用来忽略任何未知的DOM属性。 由于React无法识别,因此只会跳过它们。
// Your code:<div mycustomattribute="something" />
Would render an empty div to the DOM with React 15:
使用React 15将一个空的div呈现给DOM:
// React 15 output:<div />
In React16, the output will be the following (custom attributes will be shown and not be ignored at all):
在React16中,输出将如下所示( 将显示自定义属性,而根本不会忽略它 ):
// React 16 output:<div mycustomattribute="something" />
避免在状态为NULL的情况下重新渲染 (Avoid Re-render with setting NULL in state)
With React16 you can prevent state updates and re-renders right from setState()
. You just need to have your function return null
.
使用React16,您可以阻止状态更新并直接从setState()
重新渲染。 您只需要让函数返回null
。
const MAX_PIZZAS = 20;function addAnotherPizza(state, props) { // Stop updates and re-renders if I've had enough pizzas. if (state.pizza === MAX_PIZZAS) { return null; } // If not, keep the pizzas coming! :D return { pizza: state.pizza + 1, }}this.setState(addAnotherPizza);
Read more here.
在这里阅读更多。
创建参考 (Creating Refs)
Creating refs with React16 is now much easier. Why you need to use refs:
现在,使用React16创建引用变得容易得多。 为什么需要使用裁判:
- Managing focus, text selection, or media playback. 管理焦点,文本选择或媒体播放。
- Triggering imperative animations. 触发命令式动画。
- Integrating with third-party DOM libraries. 与第三方DOM库集成。
Refs are created using React.createRef()
and are attached to React elements via the ref
attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.
使用React.createRef()
创建React.createRef()
并通过ref
属性将其附加到React元素。 构造组件时,通常将引用分配给实例属性,以便可以在整个组件中对其进行引用。
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; }}
访问参考 (Accessing Refs)
When a ref is passed to an element in render
, a reference to the node becomes accessible at the current
attribute of the ref.
将ref传递到render
的元素时,可以在ref的current
属性处访问对节点的引用。
const node = this.myRef.current;
The value of the ref differs depending on the type of the node:
ref的值根据节点的类型而有所不同:
When the
ref
attribute is used on an HTML element, theref
created in the constructor withReact.createRef()
receives the underlying DOM element as itscurrent
property.在HTML元素上使用
ref
属性时,在带有React.createRef()
的构造函数中创建的ref
会接收底层的DOM元素作为其current
属性。When the
ref
attribute is used on a custom class component, theref
object receives the mounted instance of the component as itscurrent
.在自定义类组件上使用
ref
属性时,ref
对象将接收该组件的已安装实例作为其current
。You may not use the
ref
attribute on functional components because they don’t have instances.您不能在功能组件上使用
ref
属性,因为它们没有实例。
上下文API (Context API)
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
上下文提供了一种通过组件树传递数据的方法,而不必在每个级别手动传递道具。
React.createContext
(React.createContext
)
const {Provider, Consumer} = React.createContext(defaultValue);
Creates a { Provider, Consumer }
pair. When React renders a context Consumer
, it will read the current context value from the closest matching Provider
above it in the tree.
创建一个{ Provider, Consumer }
对。 当React渲染一个上下文Consumer
,它将从树中它上面最接近的匹配Provider
读取当前上下文值。
The defaultValue
argument is only used by a Consumer when it does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them. Note: passing undefined
as a Provider value does not cause Consumers to use defaultValue
.
仅当使用者在树中上方没有匹配的提供者时, 才使用defaultValue
参数。 这对于隔离测试组件而不包装它们很有帮助。 注意:将undefined
传递为Provider值不会导致使用者使用defaultValue
。
Provider
(Provider
)
<Provider value={/* some value */}>
A React component that allows Consumers to subscribe to context changes.
一个React组件,它允许使用者订阅上下文更改。
Accepts a value
prop to be passed to Consumers that are descendants of this Provider. One Provider can be connected to many Consumers. Providers can be nested to override values deeper within the tree.
接受要传递给作为此提供者后代的消费者的value
支持。 一个提供商可以连接到许多消费者。 可以嵌套提供程序以覆盖树中更深的值。
Consumer
(Consumer
)
<Consumer> {value => /* render something based on the context value */}</Consumer>
A React component that subscribes to context changes.
订阅上下文更改的React组件。
Requires a function as a child. The function receives the current context value and returns a React node. The value
argument passed to the function will be equal to the value
prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the value
argument will be equal to the defaultValue
that was passed to createContext()
.
需要一个孩子的功能 。 该函数接收当前上下文值并返回一个React节点。 传递给函数的value
参数将等于树中以上上下文的最接近Provider的value
prop。 如果上面的上下文没有提供者,则value
参数将等于传递给createContext()
的defaultValue
。
static getDerivedStateFromProps()
(static getDerivedStateFromProps()
)
getDerivedStateFromProps
is invoked right before calling the render method. Both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.
在调用render方法之前,将getDerivedStateFromProps
调用getDerivedStateFromProps
。 无论是在初始安装还是在后续更新中。 它应该返回一个对象以更新状态,或者返回null则不更新任何内容。
This method exists for rare use cases where the state depends on changes in props over time. For example, it might be handy for implementing a <Transiti
on> component that compares its previous and next children to decide which of them to animate in and out.
此方法适用于状态依赖于道具随时间变化的罕见用例 。 例如,实现一个<Transiti
on>组件比较上一个和下一个子对象,以确定要对其中的哪个子对象进行动画制作,可能会很方便。
Deriving state leads to verbose code and makes your components difficult to think about.
派生状态会导致冗长的代码,并使您的组件难以考虑。
Make sure you’re familiar with simpler alternatives:
If you need to perform a side effect (for example, data fetching or an animation) in response to a change in props, use
componentDidUpdate
lifecycle instead.如果您需要根据道具的变化执行副作用 (例如,数据获取或动画),请改用
componentDidUpdate
生命周期。If you want to re-compute some data only when a prop changes, use a memoization helper instead.
如果仅在更改道具时才想重新计算某些数据 ,请改用备忘录助手 。
If you want to “reset” some state when a prop changes, consider either making a component fully controlled or fully uncontrolled with a
key
instead.如果你想“复位”一些状态,当道具的变化 ,无论是考虑使组件完全控制或完全不受控制一
key
代替。
This method doesn’t have access to the component instance. If you’d like, you can reuse some code between getDerivedStateFromProps()
and the other class methods by extracting pure functions of the component props and state outside the class definition.
此方法无权访问组件实例。 如果愿意,可以通过在类定义之外提取组件props和state的纯函数来在getDerivedStateFromProps()
和其他类方法之间重用一些代码。
Note that this method is fired on every render, regardless of the cause. This is in contrast to UNSAFE_componentWillReceiveProps
. It only fires when the parent causes a re-render and not as a result of a local setState
.
请注意,无论原因如何,都会在每个渲染器上触发此方法。 这与UNSAFE_componentWillReceiveProps
相反。 仅在父级导致重新渲染而不是由于本地setState
导致时才触发。
We compare nextProps.someValue
with this.props.someValue.
If both are different then we perform some operation, setState
我们将nextProps.someValue
与this.props.someValue.
进行比较this.props.someValue.
如果两者不同,则我们执行一些操作setState
static getDerivedStateFromProps(nextProps, prevState){ if(nextProps.someValue!==prevState.someValue){ return { someState: nextProps.someValue}; } else return null;}
It receives two params nextProps
and prevState
. As mentioned previously, you cannot access this
inside this method. You’ll have to store the props in the state to compare the nextProps
with previous props. In above code nextProps
and prevState
are compared. If both are different then an object will be returned to update the state. Otherwise null
will be returned indicating state update not required. If state changes then componentDidUpdate
is called where we can perform the desired operations as we did in componentWillReceiveProps
.
它接收两个参数nextProps
和prevState
。 正如前面提到的,你不能访问this
这个方法里面。 您必须将道具存储在状态中,才能将nextProps
与以前的道具进行比较。 在上面的代码中,将nextProps
和prevState
进行了比较。 如果两者不同,则将返回一个对象以更新状态。 否则,将返回null
指示不需要更新状态。 如果状态发生变化,则将调用componentDidUpdate
,在其中我们可以像在componentWillReceiveProps
一样执行所需的操作。
奖励:React Lifecycle事件 (Bonus: React Lifecycle events)
Lifecycle credits — https://twitter.com/dceddia
生命周期积分-https: //twitter.com/dceddia
Well these are some of the features that you should definitely try while working with React16!
好了,这些是您在使用React16时一定要尝试的一些功能!
Happy coding ? ?
编码愉快吗? ?
翻译自: https://www.freecodecamp.org/news/why-react16-is-a-blessing-to-react-developers-31433bfc210a/
react和react2