Try   HackMD

React & Redux: Lesson4 Redux with React

tags: Recat2

Introduction

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

React as our UI

In this lesson, we're going to move away from our application being plain HTML and convert it to being powered by React. To do that, we'll need to add a number of libraries:

Here are the packages that we'll be adding in the next video:

<script src="https://unpkg.com/react@16.3.0-alpha.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.3.0-alpha.1/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Here's the commit with the changes made in this video.
The changes we've just implemented should look pretty familiar - they were just converting parts of our app from HTML to being powered by React Components.

Combining React and Redux

Alrighty, so you've learned React. You've built Redux and used it in a regular HTML application. But now we've started converting that HTML to a React application. In the following video we're going to start connecting the React Components to the Redux store.

I want you to pay attention to a few things in the next screencast:

  • where the store.dispatch() code goes in a React component
  • how a React component is passed the Redux store as a prop

Here's the commit with the changes made in this video.

In order to save time, we used an uncontrolled component for our input field.

ref

Refs provide a way to access DOM nodes or React elements created in the render method.

When to Use Refs

The docs outline a few good use cases for refs:

  • Managing focus, text selection, or media playback.
  • Triggering imperative animations.
  • Integrating with third-party DOM libraries.

Let's take a look at a similar example:

class Color extends React.Component {
  alertTextInput = e => {
    e.preventDefault();
    alert(this.colorElement.value);
  };

  render() {
    return (
      <div>
        <input
          type="text"
          placeholder="Add Input"
          ref={(inputElement) => this.colorElement = inputElement}
        />

        <button onClick={this.alertTextInput}>Alert Input</button>
      </div>
    );
  }
}

In the line ref={(inputElement) => this.colorElement = inputElement}, inputElement is a reference to the input DOM element. We are storing a reference to the input DOM element in the colorElement instance property of the Color class.

Please note:

React will call the ref callback with the DOM element when the component mounts, and call it with null when it unmounts. Refs are guaranteed to be up-to-date before componentDidMount or componentDidUpdate fires.
總結: ref我覺得他是在react組裝好之後才會進行呼叫,但是又比componentDidMount以及componentDidUpdate這些生命週期執行之前執行

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Here's the commit with the changes made in this video.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Here's the commit with the changes made in this video.

Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child. React will still only update the DOM if the markup changes.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Here's the commit with the changes made in this video.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Here's the commit with the changes made in this video.

Summary

In this section, we converted our plain HTML application to one using React Components. We didn't implement any new features. Instead, we just improved the code's organization by breaking out separate parts into reusable chunks.

Lesson Summary

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Lesson Challenge

Read these articles: Component State vs Redux Store and React + Redux Architecture : Separation of Concerns. Answer the following questions and share your answers with your classmates:

  1. Explain how React interplays with Redux.

  2. Give an example that illustrates the Separation of Concerns Principle.

補充說明

Babel

參考: http://skyroxas.tw/react-js-jsx-與-babel-簡介/
我們會利用JSX來產生html的element,但因為很多主流的瀏覽器不支援JSX因此我們需要透過Babel來針對JSX進行編譯,Babel不僅可以編譯JSX還可以編譯ES6

事件冒泡泡 ? preventDefault?

參考: https://ithelp.ithome.com.tw/articles/10198999

原本預期如果點其裡面的input那就會連動啟動外面div的onClick
https://ithelp.ithome.com.tw/upload/images/20180829/20106935SEmaP5JSxg.jpg

方法

  1. 使用event.stopPropagation來阻止事件冒泡
    https://ithelp.ithome.com.tw/upload/images/20180829/201069356c7lJXaO0i.jpg

  2. 使用event.preventDefault來阻止預設的動作

  • 像是<a>這個DOM本身帶有跳轉畫面的功能,如果同時在DOM裡面寫function以及url,點擊的時候會呼叫function之後就立即跳轉業面了,但是添加event.preventDefault可以讓a失去跳轉業面的功能只有執行onclick

React元件生命週期?

參考: https://www.fooish.com/reactjs/component-lifecycle.html#render

  • componentWillMount
    • 在DOM被render之前就會先執行一次 因此不可以做任何跟DOM有關的操作
    • 但比較少用 因為constructor()就可以做代替他的工作有類似的功能
    • 後來在React17準備被拿掉
  • componentDidMount
    • render之後,也就是元件被掛載到DOM後就會執行
    • 使用時機: 需要DOM或會Asynchronous更新State狀態的操作都可以使用,像是利用Ajax拉遠端的資料來進一步初始化元件

update

  • render 他其實是react中生命週期update的一環

    • 他是react.component裡面唯一必須實作的方法
    • 每次在props或是state被改變的時候就會被執行一次
    • render會根據this.props以及this.state的資料決定元件當前的UI結構和顯示內容
  • componentWillReceiveProps(nextProps)

    • will receive props 你可以想像他在props跟新的時候,提供一個nextProps的方法來跟之前的Props進行比對
      • if (this.props.initialX !== nextProps.initialX)
    • 除了第一次Render不會呼叫之外,其他像是props更新的時候或是父元件進行刷新就會呼叫
  • shouldComponentUpdate(nextProps, nextState)

    • 是一個可以讓React更有效率的方式,它的特點跟componentWillReceiveProps有點像,因為shouldcomponentupdate除了有nextProps之外還有nextState可以跟原本的props and state進行比較
    • 她有個預設的return值,在shouldcomponentUpdate被實作之前一值都是Return true表示說componentWillUpdate render componentDidUpdate都依定會執行一次,vise versa, if return false, then will not call these three functions
  • componentWillUpdate(nextProps, nextState)

    • 跟componentWillMount很像阿! render之前會先呼叫一次,但唯一的差別就是mount只會一次
    • 每次元件更新就會更新一次就變成可能會被執行好幾次,小心不要寫垃圾在裡面~
    • 不行執行setState任何會更新到元件的動作~ 畢竟render還沒準備好你就準備叫他?
    • 由於 componentWillUpdate 容易被誤解誤用,從 React 17 開始被拿掉。
  • getSnapshotBeforeUpdate(prevProps, prevState)

    • 跟樓上那位很像但她沒被拿掉?為一個差別在他像componentDidUpdate的爸爸,因為她的Return會給componentDidUpdate的第三個參數
    • 會在render之前呼叫,那你說他可以用在哪裡呢?
      • 簡單來說如果list有變動 需要幫使用者調整選軸的位置 componentDidUpdate 來得知卷軸差異來調整scroll位置
      • 但我覺得全部做在componentDidUpdate就好了呵呵
  • componentDidUpdate(prevProps, prevState, snapshot)

    • 我覺得他跟render有點像,甚至可以說是Render的小弟,他會在元件更新完成、執行完render後執行一次
    • 簡單來說也是props or state被改變後會隨著Render跟著被呼叫
    • 但是跟componentdidmount也很像?? 因為也是render之後會執行的方法之一
    • 因為render完了,所以目前的state跟props一定是最新的,就有prevProps跟prevState可以跟現在的props and state進行比對

元件的方法和屬性

元件方法 (Method) 有 setState(),而屬性 (Properties) 有 propsstate

  • component.forceUpdate(callback)
    • 通常元件會根據 Props 和 State 的改變來更新元件,但有時候元件會依賴其他的資料,這時你就需要用 this.forceUpdate() 來告訴 React 你要更新元件。
    • 執行 forceUpdate() 後 React 會跳過 shouldComponentUpdate() (可能怕return false後面都不用跑 那forceUpdate就沒有意義) 直接執行 render() (但子元件的 Lifecycle Methods 都會被正常執行)。
    • 一般實作上,需要盡量避免使用到 forceUpdate(),在 render() 中只用 this.props 和 this.state。

整理

元件生命週期事件順序
整理一下整個 Component 的生命週期發生的事件順序。

當元件第一次 render 時的順序:

  1. constructor
  2. componentWillMount, getDerivedStateFromProps
  3. render
    (React 實際更新 DOM / refs)
  4. componentDidMount

此後,當元件被更新 (update) 時的順序:

  1. componentWillReceiveProps, getDerivedStateFromProps
  2. shouldComponentUpdate - 如果 return false 就不會再往下走
  3. componentWillUpdate
  4. render
  5. getSnapshotBeforeUpdate
    (React 實際更新 DOM / refs)
  6. componentDidUpdate

其中不能執行 this.setState() 的事件: 簡單來說就是render之前的生命週期

  1. render: 正在裝dom阿
  2. componentWillMount: 還沒裝好dom阿
  3. getDerivedStateFromProps: 還沒裝好dom阿
  4. shouldComponentUpdate: 還沒裝好dom阿
  5. componentWillUpdate: 還沒裝好dom阿

到底應該使用react component state 還是使用Redux store?

參考: https://medium.com/netscape/component-state-vs-redux-store-1eb0c929277

首先我們可以把react的component分成smart and dump

  1. smart 就是裡面會牽涉到state
  2. Dump就是單純顯示資料不需要state

那何時會使用redux?

  • 很典型的例子就是購物車,裡面會有很多component但每個component必須要知道目前購物車的數量就會用到
  • 簡單來說就是多個component會需要共用到同一筆資料的時候就可以使用redux store
  • if the component use the redux store, then this is smart component.