差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

web:reactjs:react_hook:usestate [2019/02/24 22:09]
tony
web:reactjs:react_hook:usestate [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​reactjs}} 
-====== React Hook - useState ====== 
-===== Introduction ===== 
-在我研究React到現在,我認為React是基於state去決定UI該怎麼呈現。在2018年React提出了Hook,賦予了Function Component擁有了React State的概念。我以大家最常使用的Counter範例,來分享用法。一個Counter UI,它透過div顯示次數,透過點擊button去增加次數;在使用React Component的寫法時,程式碼如下,你必須透過this.state宣告member,而透過setState告知React狀態的改變:​ 
-<code javascript>​ 
-import React, { Component } from "​react"​ 
  
-class CounterComp extends Component { 
-    constructor(prop){ 
-        super(prop);​ 
-        this.state = { count: 0 }; 
-    } 
- 
-    render(){ 
-        const { count } = this.state; 
-        return ( 
-            <> 
-                <div aria-label="​counter-val">​This is a example: {count}.</​div>​ 
-                <button onClick={() => { this.setState({ count: count + 1 }); }}>​count+1</​button>​ 
-            </> ​   ​ 
-        ); 
-    } 
-} 
- 
-export default CounterComp 
-</​code>​ 
-只要你做了setState後,相關的元件就會做出對應的改變。接下來的文章將分享如何改成useState的形式與對應測試該怎麼寫。 
-===== useState ===== 
-首先看看程式碼量的差異:​ 
-<code javascript>​ 
-import React, { useState } from "​react"​ 
- 
-function CounterFunc() { 
-    const [ count, setCount ] = useState(0);​ 
- 
-    return ( 
-        <> 
-            <div aria-label="​counter-val">​This is a example: {count}.</​div>​ 
-            <button onClick={()=>​setCount(count+1)}>​count+1</​button>​ 
-        </> 
-    ) 
-} 
- 
-export default CounterFunc 
-</​code>​ 
-首先透過useState賦予count預設值,內容也可以是json;而setCount是用來修改count的狀態。接著在button中綁定一個函式,呼叫setCount並把新的值設定進去即可。是不是很簡單?​ 
-===== Unit Test ===== 
-一開始我使用了enzyme去測試改完的程式碼:​ 
-<code javascript>​ 
-it('​Test click button of counterFunc',​ ()=>{ 
-    const counterFunc = shallow(<​CounterFunc/>​);​ 
-    counterFunc.find('​button'​).simulate('​click'​);​ 
-    expect(counterFunc.find('​div'​).text()).toBe('​This is a example: 1.'); 
-}); 
-</​code>​ 
-但我發現click並無法觸發狀態的改變。爬一下文,發現這目前是enzyme的問題[[https://​github.com/​reactjs/​rfcs/​issues/​71|link]],也許以後某天會改。因此我改用react-testing-library做測試:​ 
-<code javascript>​ 
-import CounterFunc from "​../​CounterFunc";​ 
-import {render, fireEvent, cleanup} from '​react-testing-library';​ 
-import React from '​react';​ 
-import renderer from '​react-test-renderer';​ 
-import {shallow} from '​enzyme';​ 
- 
- 
-describe('<​CounterFunc>',​()=>​{ 
-    afterEach(cleanup);​ 
- 
-    it('​CounterFunc snapshot',​ () => { 
-        const tree = renderer.create(<​CounterFunc/>​).toJSON() 
-        expect(tree).toMatchSnapshot();​ 
-    }) 
- 
-    // //​Can'​t work with React-Hook 
-    // it('​Test click button of counterFunc',​ ()=>{ 
-    //     const counterFunc = shallow(<​CounterFunc/>​);​ 
-    //     ​counterFunc.find('​button'​).simulate('​click'​);​ 
-    //     ​expect(counterFunc.find('​div'​).text()).toBe('​This is a example: 1.'); 
-    // }); 
- 
-    it('​Test click button of counterFunc',​ ()=>{ 
-        const utils = render(<​CounterFunc/>​);​ 
-        const display = utils.getByLabelText('​counter-val'​);​ 
-        const button = utils.getByText('​count+1'​);​ 
- 
-        fireEvent.click(button);​ 
-        expect(display.textContent).toBe('​This is a example: 1.'); 
-    }); 
-}); 
-</​code>​ 
-===== Reference ===== 
-  * [[https://​reactjs.org/​docs/​hooks-state.html|reactjs - hooks state]] 
-  * [[https://​jestjs.io/​docs/​en/​getting-started|jest - getting-started]] 
- 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~