摘要:結果如下打開試試下一步,我們將把組件功能自己設置定時器并且能每秒更新。這是一個設置定時器的好地方注意我們是怎么保存定時器的。我們將在這個生命周期的函數方法中卸載掉定時器最后,我們會每一秒跑方法。
下面是react官方文檔的個人翻譯,如有翻譯錯誤,請多多指出
原文地址:https://facebook.github.io/re...
Consider the ticking clock example from one of the previous sections.
思考一下,我們之前提到過的時鐘例子。
So far we have only learned one way to update the UI.
到目前為止,我們只學到一種更新UI的方式。
We call ReactDOM.render() to change the rendered output:
我們調用ReactDOM.render()的方法來改變渲染的輸出:
function tick() { const element = (); ReactDOM.render( element, document.getElementById("root") ); } setInterval(tick, 1000);Hello, world!
It is {new Date().toLocaleTimeString()}.
打開試試
In this section, we will learn how to make the Clock component truly reusable and encapsulated.
在這一章,我們會學到怎么把Clock組件變得真正的可重用以及封裝。
It will set up its own timer and update itself every second.
這會讓配置我們的timer組件并且每秒自我更新。
We can start by encapsulating how the clock looks:
我們從怎么封裝Clock開始:
function Clock(props) { return (); } function tick() { ReactDOM.render(Hello, world!
It is {props.date.toLocaleTimeString()}.
, document.getElementById("root") ); } setInterval(tick, 1000);
打開試試
However, it misses a crucial requirement: the fact that the Clock sets up a timer and updates the UI every second should be an implementation detail of the Clock.
然而,這會錯過一個至關重要的需求: Clock設置一個計時器并且每秒鐘更新UI是一個時鐘的實現細節。
Ideally we want to write this once and have the Clock update itself:
理想狀況下,我們先寫一次然后這個Clock能自我更新:
ReactDOM.render(, document.getElementById("root") );
To implement this, we need to add "state" to the Clock component.
要實現這一點,我們需要添加“state” 到 Clock組件。
State is similar to props, but it is private and fully controlled by the component.
state跟porps很相似,但是這是組件私有的并且是受組件控制的。
We mentioned before that components defined as classes have some additional features.
我們在前面提及過,用類的形式定義組件有一些額外的功能。
Local state is exactly that: a feature available only to classes.
本地state就是:只有一個特征類。
將一個函數轉換為一個類
You can convert a functional component like Clock to a class in five steps:
你能通過五步把一個函數組件轉化為類組件
Create an ES6 class with the same name that extends React.Component. 創建一個同名的類組件并且繼承React.Compoent
Add a single empty method to it called render().添加一個空的方法叫做render()
Move the body of the function into the render() method.把函數里面的內容移到render方法里面。
Replace props with this.props in the render() body.把render()里面的props替換成this.props
Delete the remaining empty function declaration.刪掉之前的函數聲明的組件。
class Clock extends React.Component { render() { return (); } }Hello, world!
It is {this.props.date.toLocaleTimeString()}.
打開試試
Clock is now defined as a class rather than a function.
Clock現在定義成一個類組件比定義成函數組件好。
This lets us use additional features such as local state and lifecycle hooks.
因為這讓我們添加一些新的功能例如本地state以及生命周期。
添加State
We will move the date from props to state in three steps:
我們將用三步把props移到state:
1) Replace this.props.date with this.state.date in the render() method:
把render()方法里的this.props.date替換成 this.state.date
class Clock extends React.Component { render() { return (); } }Hello, world!
It is {this.state.date.toLocaleTimeString()}.
2) Add a class constructor that assigns the initial this.state:
添加class constructor 用來初始化this.state:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return (); } }Hello, world!
It is {this.state.date.toLocaleTimeString()}.
Note how we pass props to the base constructor:
注意,我們是怎么把props傳遞到constructor的:
constructor(props) { super(props); this.state = {date: new Date()}; }
Class components should always call the base constructor with props.
類組件應該調用constructor時候帶著props
3) Remove the date prop from the
把
ReactDOM.render(, document.getElementById("root") );
We will later add the timer code back to the component itself.
我們將會添加回定時器代碼到組件本身。
The result looks like this:
結果如下:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return (); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, document.getElementById("root") );
打開試試
Next, we"ll make the Clock set up its own timer and update itself every second.
下一步,我們將把組件功能自己設置定時器并且能每秒更新。
添加周期方法到類組件
In applications with many components, it"s very important to free up resources taken by the components when they are destroyed.
在有許多組件的應用里, 當組件被銷毀的時候釋放掉資源是非常重要的。
We want to set up a timer whenever the Clock is rendered to the DOM for the first time.
我們想讓Clock組件在第一次渲染在DOM的時候設置定時器。
This is called "mounting" in React.
我們在React中稱為"mounting"。
We also want to clear that timer whenever the DOM produced by the Clock is removed.
我們同樣當組件被移除的手請
This is called "unmounting" in React.
我們在React中稱為"unmounting"。
We can declare special methods on the component class to run some code when a component mounts and unmounts:
我們在類組件里生命一些特別的方法當組件mounts和 unmounts的時候去運行一些代碼:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } componentDidMount() { } componentWillUnmount() { } render() { return (); } }Hello, world!
It is {this.state.date.toLocaleTimeString()}.
These methods are called "lifecycle hooks".
這些方法被稱為“生命周期方法鉤子"。
The componentDidMount() hook runs after the component output has been rendered to the DOM. This is a good place to set up a timer:
這個componentDidMount的方法會在組件渲染在dom上后被調用。這是一個設置定時器的好地方:
componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); }
Note how we save the timer ID right on this.
注意我們是怎么保存定時器ID的。
While this.props is set up by React itself and this.state has a special meaning, you are free to add additional fields to the class manually if you need to store something that is not used for the visual output.
當this.props被初始化在React,而且 this.state有一個特殊的意義,你可以手動地自由地添加額外的字段到類中,如果你需要存儲一些你不被用來輸出渲染
If you don"t use something in render(), it shouldn"t be in the state.
如果你不使用render()方法,就不應該用在state里。
We will tear down the timer in the componentWillUnmount() lifecycle hook:
我們將在componentWillUnmount這個生命周期的函數方法中卸載掉定時器:
componentWillUnmount() { clearInterval(this.timerID); }
Finally, we will implement the tick() method that runs every second.
最后,我們會每一秒跑tick()方法。
It will use this.setState() to schedule updates to the component local state:
我們會用this.setState()來安排組件本地的state更新:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return (); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, document.getElementById("root") );
打開試試
Now the clock ticks every second.
現在,時鐘每一秒都在轉動。
Let"s quickly recap what"s going on and the order in which the methods are called:
讓我們快速回顧一下,發生了什么并且我們是怎么去調用這些方法的。
1) When
當
Since Clock needs to display the current time, it initializes this.state with an object including the current time.
由于Clock需要顯示正確的時間,因此我們初始化this.state成一個object包含這正確的時間。
We will later update this state.
我們稍后會更新這個state。
2) React then calls the Clock component"s render() method. This is how React learns what should be displayed on the screen.
React 稍后會調用Clock組件的render()方法。這就是React怎樣知道什么東西應該渲染到界面上。
React then updates the DOM to match the Clock"s render output.
React 稍后會更新DOM來保證Clock正確的渲染輸出
3) When the Clock output is inserted in the DOM, React calls the componentDidMount() lifecycle hook.
當Clock輸出被插入到DOM里面,React會調用componentDidMount()的方法。
Inside it, the Clock component asks the browser to set up a timer to call tick() once a second.
之后,Clock組件會在瀏覽器里設置定時器并且開始tick()方法。
4) Every second the browser calls the tick() method.
每一秒瀏覽器調用tick方法。
Inside it, the Clock component schedules a UI update by calling setState() with an object containing the current time.
在里面,Clock組件會安排一個UI通過調用setState()并且傳入一個時間的對象來更新。
Thanks to the setState() call, React knows the state has changed, and calls render() method again to learn what should be on the screen.
由于setState()調用,React知道state的改變,并且再次調用render()方法來讓界面知道怎么改變。
This time, this.state.date in the render() method will be different, and so the render output will include the updated time.
這一次,this.state.data在render()方法將會不一樣,所以渲染接輸出講包括更新時間。
React updates the DOM accordingly.
React相應地更新DOM。
5) If the Clock component is ever removed from the DOM, React calls the componentWillUnmount() lifecycle hook so the timer is stopped.
如果Clock組件要從DOM外移除,React會調用componentWillUnmount()函數,并且是定時器停止。
正確使用State
There are three things you should know about setState().
有三件關于的setState的事你必須知道
別直接修改State的值
For example, this will not re-render a component:
例如,這不會重新渲染一個組件:
// Wrong this.state.comment = "Hello";
Instead, use setState():
我們要用setState()來代替:
// Correct this.setState({comment: "Hello"});
The only place where you can assign this.state is the constructor.
你唯一能聲明this.state的地方只有在constructor里
State的更新有可能是異步的
React may batch multiple setState() calls into a single update for performance.
React 為了性能,可能會把批量處理多次的setState() 調用在一個的更新里。
Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
因為this.props和this.state可能異步更新了,你不應該依賴他們的值來計算下一個state。
For example, this code may fail to update the counter:
例如, 下面的代碼可能會更新計算器失敗:
// Wrong this.setState({ counter: this.state.counter + this.props.increment, });
To fix it, use a second form of setState() that accepts a function rather than an object.
為了解決這個問題,讓setState()接收一個函數比接收一個對象的方式更好。
That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
這個函數會把前一個state作為第一個參數, 并且props在那時更新并被作為第二參數:
// Correct this.setState((prevState, props) => ({ counter: prevState.counter + props.increment }));
We used an arrow function above, but it also works with regular functions:
我們在上面的函數用了箭頭函數,我們使用常規的函數也一樣可用:
// Correct this.setState(function(prevState, props) { return { counter: prevState.counter + props.increment }; });State Updates are Merged
state的更新是合并后的
When you call setState(), React merges the object you provide into the current state.
當你調用setState(),React會合并你提供的對象到當前的state里。
For example, your state may contain several independent variables:
例如:你的state可能包含幾個獨立的變量:
constructor(props) { super(props); this.state = { posts: [], comments: [] }; }
Then you can update them independently with separate setState() calls:
然后你就能獨立更新他們通過多帶帶調用setState():
componentDidMount() { fetchPosts().then(response => { this.setState({ posts: response.posts }); }); fetchComments().then(response => { this.setState({ comments: response.comments }); }); }
The merging is shallow, so this.setState({comments}) leaves this.state.posts intact, but completely replaces this.state.comments.
這個合并是淺合并,所以this.setState({comments})會讓this.state.posts完整,但是會完全替換掉this.state.comments.
單向數據流
Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn"t care whether it is defined as a function or a class.
所有的父組件或者子組件都不知道一個組件是stateful或者stateless的,并且他們也不應該關心自己是被定義成一個函數或者是類組件。
This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.
這就是為什么state經常被本地調用或者被封裝。對于別的組件來說,組件的擁有的state是不可被訪問的。
A component may choose to pass its state down as props to its child components:
一個組件可能會把自己的state作為props傳遞給他們的子組件中:
It is {this.state.date.toLocaleTimeString()}.
This also works for user-defined components:
這同樣適用用戶定義的組件中:
The FormattedDate component would receive the date in its props and wouldn"t know whether it came from the Clock"s state, from the Clock"s props, or was typed by hand:
FormattedDate組件將會接收data作為他的props并且將不知道他是來自哪,是Clock"s state,是來自Clock"s state, 還是來自手動輸入的。
function FormattedDate(props) { returnIt is {props.date.toLocaleTimeString()}.
; }
打開試試
This is commonly called a "top-down" or "unidirectional" data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components "below" them in the tree.
這就是我們平常所說的從上往下或者單向數據流。任何的state都是屬于一些特定的組件,并且任何的數據或者UI視圖 只能影響在他組件樹下面的的組件。
If you imagine a component tree as a waterfall of props, each component"s state is like an additional water source that joins it at an arbitrary point but also flows down.
如果你把一個組件的props想象成是瀑布,每一個組件的state就像一個額外的水資源,并且這在任意點處鏈接還往下流。
To show that all components are truly isolated, we can create an App component that renders three
為了展示所有的組件都是孤立的,我們創建一個App組件來渲染三個
function App() { return (); } ReactDOM.render(, document.getElementById("root") );
打開試試
Each Clock sets up its own timer and updates independently.
每個Clock都會獨立設置以及更新自己的定時器。
In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time.
在React app里,無論一個stateful or stateless的組件都被認為組件獨立的細節都可能隨著時間而改變。
You can use stateless components inside stateful components, and vice versa.
你能用stateless組件代替stateful組件,反之亦然。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81906.html
摘要:譯的生命周期的使用場景原文鏈接作者翻譯上名這個圖片,就是組件的生命周期,從形成到銷毀的過程。這并不意味著沒有用。最常見的用例更新以響應或更改。是否可以調用總結在理想的世界中,我們不會使用生命周期方法。 [譯]React 的生命周期的使用場景 showImg(https://segmentfault.com/img/bVLTCt?w=2000&h=800); 原文鏈接:React Lif...
摘要:將的生命周期函數對應成,生命周期改變,會造成改變,而變化將觸發事件,從而被接收。與一樣,都是通過注冊來監聽的生命周期回調,來給每個添加的。 版權聲明:本文已授權微信公眾號:Android必修課,轉載請申明出處眾所周知,Android凡是需要展示給用戶看的,都包含著生命周期這個概念,例如Activity、Fragment、View等都與生命周期息息相關,在生命周期函數里,它們各自完成創...
摘要:使用詳解使用詳解源碼解剖源碼解剖地址技術人,一位不羈的碼農。在中,它默認為我們初始化,作為一個成員變量。在方法中,它會判斷我們是否已經添加,沒有的話,添加進去。說在前面 本次推出 Android Architecture Components 系列文章,目前寫好了四篇,主要是關于 lifecycle,livedata 的使用和源碼分析,其余的 Navigation, Paging libr...
閱讀 1655·2021-09-26 09:55
閱讀 5248·2021-09-22 15:40
閱讀 2013·2019-08-30 15:53
閱讀 1497·2019-08-30 11:15
閱讀 1715·2019-08-29 15:41
閱讀 1869·2019-08-28 18:13
閱讀 3146·2019-08-26 12:00
閱讀 1668·2019-08-26 10:30