翻譯練習(xí) react-組件和props

狀態(tài)和生命周期
State and Lifecycle

This page introduces the concept of state and lifecycle in a React component. You can find a detailed component API reference here.
這一頁(yè)介紹React組件關(guān)于狀態(tài)的概念和聲明周期入问。你可以在這里找到組件涉及的詳細(xì)api

Consider the ticking clock example from one of the previous sections. In Rendering Elements, we have only learned one way to update the UI. We call ReactDOM.render() to change the rendered output:
思考下上一個(gè)部分那個(gè)時(shí)鐘的例子邑闺。在渲染元素中嚷掠,我門只學(xué)歷一種方式去更新ui团甲,我們調(diào)用React.render()去改變渲染的輸出

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

Try it on CodePen
在CodePen中試一試

In this section, we will learn how to make the Clock component truly reusable and encapsulated. It will set up its own timer and update itself every second.
在這個(gè)部分稚补,我們將學(xué)習(xí)怎么讓Clock組件實(shí)現(xiàn)真正的可復(fù)用和封閉性摸屠。它將建立它自己的定時(shí)器并每秒更新一次鲜结。

We can start by encapsulating how the clock looks:
我門開(kāi)始學(xué)習(xí)如何去封裝時(shí)鐘的外觀吧

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

Try it on CodePen
在CodePen中嘗試一下

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.
然而域那,它忽略了一個(gè)關(guān)鍵的要求,時(shí)鐘設(shè)置定時(shí)器并每秒鐘更新审编,這個(gè)應(yīng)該是定時(shí)器的實(shí)現(xiàn)細(xì)節(jié)

Ideally we want to write this once and have the Clock update itself:
理想情況下撼班,我門想寫一次就能讓時(shí)Clock現(xiàn)自我更新

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

To implement this, we need to add “state” to the Clock component.
為了實(shí)現(xiàn)它,我門需要添加一個(gè)state在Clock組件里面

State is similar to props, but it is private and fully controlled by the component.
State和props很像垒酬,但是它是組件里面私有的并完全由該組件控制的

Converting a Function to a Class
把 一個(gè)Function 轉(zhuǎn)化為 一個(gè) Class

You can convert a function component like Clock to a class in five steps:
你可以通過(guò)五步把一個(gè)類似Clock這樣的函數(shù)組件轉(zhuǎn)化為class組件

  1. Create an ES6 class, with the same name, that extends React.Component.
  2. Add a single empty method to it called render().
  3. Move the body of the function into the render() method.
  4. Replace props with this.props in the render() body.
  5. Delete the remaining empty function declaration.
  6. 創(chuàng)建一個(gè)class砰嘁,用相同的名稱,如何extends React勘究。Component
  7. 新增一個(gè)空的render 方法
  8. 移動(dòng)function的內(nèi)容到render方法里面去
  9. 吧render內(nèi)容里面的props替換為this矮湘。props
  10. 刪除遺留的空函數(shù)的聲明
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

Try it on CodePen
在CodePen上試一下

Clock is now defined as a class rather than a function.
Clock現(xiàn)在的定義為一個(gè)class而不是一個(gè)函數(shù)

The render method will be called each time an update happens, but as long as we render <Clock /> into the same DOM node, only a single instance of the Clock class will be used. This lets us use additional features such as local state and lifecycle methods.
render方法將會(huì)在每次更新的時(shí)候調(diào)用,但是一旦在同一個(gè)dom節(jié)點(diǎn)內(nèi)渲染<Clock />口糕,被使用的同一個(gè)Clock的實(shí)例缅阳。

This lets us use additional features such as local state and lifecycle methods.
這時(shí),我們需要使用另外的特性例如組件內(nèi)的state和生命周期方法

Adding Local State to a Class
加入一個(gè)本地狀態(tài)到class中

We will move the date from props to state in three steps:
我們將通過(guò)三個(gè)步驟把props的數(shù)據(jù)移動(dòng)到state

  1. Replace this.props.date with this.state.date in the render() method:
    把render方法中的this.state.date替換為this.props.date
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
  1. Add a class constructor that assigns the initial this.state:
    加入一個(gè)class的構(gòu)造器屬性初始化this.state
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

Note how we pass props to the base constructor:
注意我們是怎么通過(guò)傳遞props到一個(gè)基礎(chǔ)的構(gòu)造器里面的

  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

Class components should always call the base constructor with props.
class組件應(yīng)該總是通過(guò)調(diào)用構(gòu)造器屬性獲得props

3.Remove the date prop from the <Clock /> element:
移除<Clock />組件上的date prop

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

We will later add the timer code back to the component itself.
我們將在后面往組件內(nèi)添加定時(shí)器代碼

The result looks like this:
結(jié)果看起來(lái)就像這樣

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

Next, we’ll make the Clock set up its own timer and update itself every second.
下一步景描,我門將建立Clock自己的定時(shí)器實(shí)現(xiàn)每一秒更新自己

Adding Lifecycle Methods to a Class
加入生命周期方法到Class內(nèi)

In applications with many components, it’s very important to free up resources taken by the components when they are destroyed.
在具有許多組件的應(yīng)用中十办,當(dāng)組件被銷毀的時(shí)候釋放占用的內(nèi)存是非常重要的。

We want to set up a timer whenever the Clock is rendered to the DOM for the first time. This is called “mounting” in React.
我們想在Clock被渲染成dom之后的第一時(shí)間建立一個(gè)定時(shí)器超棺,這個(gè)時(shí)候在React被稱為“mounting”

We also want to clear that timer whenever the DOM produced by the Clock is removed. This is called “unmounting” in React.
我們也想要在Clock組件被清除的時(shí)候清空定時(shí)器向族。這個(gè)時(shí)候在React被稱為“unmounting”

We can declare special methods on the component class to run some code when a component mounts and unmounts:
我們可以在組件mounts或unmounts的時(shí)候調(diào)用一個(gè)特殊的方法去執(zhí)行一些代碼

These methods are called “l(fā)ifecycle methods”.
這些方法被稱為生命周期

The componentDidMount() method runs after the component output has been rendered to the DOM. This is a good place to set up a timer:
這個(gè)componentDidMount方法在組件以及被渲染之后調(diào)用,這時(shí)一個(gè)創(chuàng)建定時(shí)器的好地方

 componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

Note how we save the timer ID right on this (this.timerID).
注意我們?cè)趺凑_通過(guò)this保存定時(shí)器的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 doesn’t participate in the data flow (like a timer ID).
盡管this.prrops和this.state都是React自己創(chuàng)建的说搅,且都有特殊的意思炸枣,但是你以可以手動(dòng)的添加一些額外的字段給class去儲(chǔ)存一些不參與數(shù)據(jù)流的字段

We will tear down the timer in the componentWillUnmount() lifecycle method:
我們將清除那個(gè)定時(shí)在在ComponentWillUnmount的生命周期當(dāng)中

componentWillUnmount() {
    clearInterval(this.timerID);
  }

Finally, we will implement a method called tick() that the Clock component will run every second.
最后,我門將實(shí)現(xiàn)一個(gè)方法調(diào)用Clock組件使它每一秒都運(yùn)轉(zhuǎn)起來(lái)

It will use this.setState() to schedule updates to the component local state:
這個(gè)方法是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 (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

Now the clock ticks every second.
現(xiàn)在時(shí)鐘每一秒都會(huì)刷新

Let’s quickly recap what’s going on and the order in which the methods are called:
讓我門快速回顧一下發(fā)生了些什么和這些方法被調(diào)用的順序

When <Clock /> is passed to ReactDOM.render(), React calls the constructor of the Clock component. Since Clock needs to display the current time, it initializes this.state with an object including the current time. We will later update this state.

  1. 當(dāng)把<Clock />傳遞給ReactDom适肠。render()霍衫,React會(huì)調(diào)用Clock的構(gòu)造器屬性。因?yàn)镃lock需要展示當(dāng)前時(shí)間侯养,它會(huì)初始化this敦跌。state,這是一個(gè)包含當(dāng)前時(shí)間的對(duì)象逛揩。我們將在后面更新這個(gè)state

React then calls the Clock component’s render() method. This is how React learns what should be displayed on the screen. React then updates the DOM to match the Clock’s render output.

  1. 然后React 調(diào)用Clock 組件的render()方法柠傍。這是React知道在屏幕上要展現(xiàn)什么的方式。然后React會(huì)匹配Clock的渲染輸出更新dom

When the Clock output is inserted in the DOM, React calls the componentDidMount() lifecycle method. Inside it, the Clock component asks the browser to set up a timer to call the component’s tick() method once a second.

  1. 當(dāng)Clock 輸出插入到dom之后辩稽,React調(diào)用componentDidMount生命周期方法惧笛。在這里,Clock組件會(huì)要求瀏覽器構(gòu)建一個(gè)定時(shí)器每一秒去調(diào)用組件的tick()方法

Every second the browser calls the tick() method. Inside it, the Clock component schedules a UI update by calling setState() with an object containing the current time. Thanks to the setState() call, React knows the state has changed, and calls the render() method again to learn what should be on the screen. This time, this.state.date in the render() method will be different, and so the render output will include the updated time. React updates the DOM accordingly.
4.每一秒瀏覽器都會(huì)調(diào)用tick方法逞泄,在這里患整,Clock組件通過(guò)調(diào)用setState()傳入一個(gè)包含當(dāng)前時(shí)間的對(duì)象去安排ui更新。因?yàn)閟etState()的調(diào)用喷众,React知道state改變了各谚,并調(diào)用render方法再次去拿到當(dāng)前屏幕展示的元素。在這時(shí)到千,this昌渤。state。data在render()方法厘米昂將會(huì)改變憔四,所以渲染輸出將會(huì)包含更新的時(shí)間膀息。因此React更新了dom

If the Clock component is ever removed from the DOM, React calls the componentWillUnmount() lifecycle method so the timer is stopped.
5.如果Clock組件一旦從dom中一出。React會(huì)調(diào)用componeWillUnmount()生命周期方法使定時(shí)器被停止

Using State Correctly
正確的使用state

There are three things you should know about setState().
關(guān)于setState有三件事情是你應(yīng)該要知道的

Do Not Modify State Directly
不要直接修改State

For example, this will not re-render a component:
例如加矛,這樣操作并不會(huì)引起組件的再次渲染

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.
你只有在構(gòu)造器里面才可以直接賦值this。state的

State Updates May Be Asynchronous
狀態(tài)更新可能是異步的

React may batch multiple setState() calls into a single update for performance.
React可能會(huì)把多個(gè)setState調(diào)用合成一個(gè)

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
因?yàn)閠his斟览。props和this。state可能是異步更新的辑奈,你不應(yīng)該依賴他們的指去計(jì)算新的state

For example, this code may fail to update the counter:
例如苛茂,這個(gè)代碼可能會(huì)導(dǎo)致conter更新失敗

// 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. 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:
正確的做法是使用setState()接收一個(gè)函數(shù)而不是一個(gè)對(duì)象。這個(gè)函數(shù)將會(huì)接收上一次的state作為第一個(gè)參數(shù)鸠窗,和此次被更新調(diào)用的props作為第二個(gè)參數(shù)

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

We used an arrow function above, but it also works with regular functions:
在上面的例子中妓羊,我們使用了一個(gè)箭頭函數(shù),但是它也可以使用普通函數(shù)

// Correct
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

State Updates are Merged
狀態(tài)更新和合并

When you call setState(), React merges the object you provide into the current state.
當(dāng)你調(diào)用setState()稍计,Reacft會(huì)合并你當(dāng)前提供的對(duì)象和state對(duì)象

For example, your state may contain several independent variables:
例如躁绸,你的state可能包含幾個(gè)獨(dú)立的變量

 constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

Then you can update them independently with separate setState() calls:
當(dāng)你各自通過(guò)setState去更新他們時(shí)

  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

The Data Flows Down
數(shù)據(jù)是向下流動(dòng)的

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.
無(wú)論父組件還是子組件都無(wú)法知道某個(gè)組件是有狀態(tài)的還是無(wú)狀態(tài)的,并且他們也不會(huì)關(guān)心是函數(shù)組件還是class組件

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.
這是為什么狀態(tài)通常是局部調(diào)用或者封閉的净刮。除了擁有并設(shè)置它的組件剥哑,其他都無(wú)法去訪問(wèn)它

A component may choose to pass its state down as props to its child components:
一個(gè)組件可以選擇向下傳遞它的狀態(tài)給子組件的props

<h2>It is {this.state.date.toLocaleTimeString()}.</h2>

This also works for user-defined components:
這在自定義組件同樣適用

<FormattedDate date={this.state.date} />

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 組件將會(huì)在它的props里接收到date而且它并不知道是來(lái)自于Clock的state,來(lái)自于Clock的props又或者是手動(dòng)傳入的

function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}

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.
這是種方式通常會(huì)被稱為由上而下或者是單向的數(shù)據(jù)流淹父。任何state總是屬于特定的組件株婴,并且從它衍生出來(lái)的任何數(shù)據(jù)或者ui都只能影響在樹(shù)中在它下方的組件

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.
如果你把一個(gè)組件樹(shù)想象成一個(gè)props數(shù)據(jù)的瀑布。那么每一個(gè)組件的state就像在任意的點(diǎn)上加的一個(gè)額外的水資源暑认,但是它們也是向下流動(dòng)的

To show that all components are truly isolated, we can create an App component that renders three <Clock>s:
為了展示所有組件是獨(dú)立的困介,我們可以創(chuàng)建一個(gè)app組件渲染三個(gè)<Clock >

function App() {
  return (
    <div>
      <Clock />
      <Clock />
      <Clock />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

Each Clock sets up its own timer and updates independently.
每一個(gè)Clock都會(huì)建立它們自己的定時(shí)器和獨(dú)立的更新數(shù)據(jù)

In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa.
在React 應(yīng)用中,一個(gè)組件是有狀態(tài)或者是無(wú)狀態(tài)的是組件內(nèi)部實(shí)現(xiàn)的細(xì)節(jié)蘸际。它可能會(huì)隨著時(shí)間推移而改變座哩。你可以在一個(gè)有狀態(tài)組件內(nèi)使用無(wú)狀態(tài)組件,反之亦然

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粮彤,一起剝皮案震驚了整個(gè)濱河市根穷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驾诈,老刑警劉巖缠诅,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異乍迄,居然都是意外死亡管引,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門闯两,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)褥伴,“玉大人,你說(shuō)我怎么就攤上這事漾狼≈芈” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵逊躁,是天一觀的道長(zhǎng)似踱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)稽煤,這世上最難降的妖魔是什么核芽? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮酵熙,結(jié)果婚禮上轧简,老公的妹妹穿的比我還像新娘。我一直安慰自己匾二,他們只是感情好哮独,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布拳芙。 她就那樣靜靜地躺著,像睡著了一般皮璧。 火紅的嫁衣襯著肌膚如雪舟扎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天恶导,我揣著相機(jī)與錄音浆竭,去河邊找鬼。 笑死惨寿,一個(gè)胖子當(dāng)著我的面吹牛邦泄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裂垦,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼顺囊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蕉拢?” 一聲冷哼從身側(cè)響起特碳,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晕换,沒(méi)想到半個(gè)月后午乓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闸准,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年益愈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夷家。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒸其,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出库快,到底是詐尸還是另有隱情摸袁,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布义屏,位于F島的核電站靠汁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闽铐。R本人自食惡果不足惜膀曾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阳啥。 院中可真熱鬧,春花似錦财喳、人聲如沸察迟。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扎瓶。三九已至所踊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間概荷,已是汗流浹背秕岛。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留误证,地道東北人继薛。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像愈捅,于是被迫代替她去往敵國(guó)和親遏考。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容