---
# System prepended metadata

title: '[自行分析] React 作業 Week23'
tags: [React, review]

---

# [自行分析] React 作業 Week23	

###### tags: `review` `React`

## HW1

> 延續上週的作業，我們這次要把 Redux 給加進來。就如同我們教過的一樣，Redux 通常適合用在儲存「global 的狀態」，因此在這個作業中你必須增加把 Navbar 的部分改成用 Redux 來處理，所以你應該會在 store 裡面儲存現在所在的分頁，而且還需要建立一個 action 來改變分頁的狀態。

其實這題我也是依樣畫葫蘆做出來的, 不敢說自己對`Redux` 真的很熟
就拿老師的範例改一改而已. 

其實老師有提示, 這篇文章我先從提示來切入

### 把 Navbar 的部分改成用 Redux 

這邊要實作`tab`功能, 所以要先發想我`tab`的動作, 那就是我會點選`onClick`並給予他新的值
```javascript=
 onClick={() => {this.props.updateTab('Home') }}
```
哪這`updateTab`哪來的? 這是`dispatch`來的, `dispatch`怎麼來的? 從`action`來的

### 而且還需要建立一個 action 來改變分頁的狀態

這時候我需要新`action`, 新`action`建立前, 會先定義好`actionTypes`
```javascript=
//actionTypes
export const UPDATE_NAV_TAB = 'UPDATE_NAV_TAB'
```

接著
```javascript=
//這邊定義我會透過這個function來改變, name的值
export const updateNavTab = (tab) => {
    return {
        type: actionTypes.UPDATE_NAV_TAB,
        name: tab
    }
}
```
### 所以你應該會在 store 裡面儲存現在所在的分頁

`store`的建立是因為`reducer`, 要在`reducer`裡面建立新的`state`

```javascript=
const state = {
    navTab: 'Home',
}
```

接下來就是優雅的調用

```javascript=
case actionTypes.UPDATE_NAV_TAB:
    return {
        ...globalState,
        navTab: action.name
    }		
```

再來就是卡我卡最久的, 我的`state`和`props`要分別放在哪? 
根據課堂上的教學, 這些資料都會放在`container`裡面, 完全和`component`隔開

所以直接進入`navTabContainer`, 這邊就呼應了`onClick`
```javascript=

import { connect } from 'react-redux'

const navTabContainer = (props) => {
    return <Nav {...props} />
}


const mapDispatchToProps = dispatch => {
    return {
		//我要用updateTab這個function, 然後他是調用action裡面的updateNavTab
        updateTab: tab => dispatch(updateNavTab(tab))
    }
}

//要和Nav做連結
export default connect(null, mapDispatchToProps)(Nav);
```

既然已經選好了`props`,那我的`state`呢? 
我在`App`裡面有做好這個功能, 但是沒有`appContainer`怎麼辦?

==直接在`<App />`裡面做好就好拉==

```javascript=
const mapStateToProps = state => {
  return {
    navTab: state.nav.navTab
  }
}

export default connect(mapStateToProps, null)(App)
```
當然你要先在這邊定義好, 我如果現在是什麼`state`那就會render出什麼

```javascript=
{this.props.navTab === 'Home' && <Home />}
.....
....
```
其他就依此類推了, 其實我覺得不是很難, 但是老師放水放很大?

### 20191110

後來我問了Huli, 他說本來就有router沒錯, 但是就是拿來給我們練習的
所以可以實作出來很好, 但也不一定要用`redux`的方法, 我自己認為
我已經算是懂了, 就不再追究了下去了

### 20191111

#### 編輯功能

其實編輯功能, 最重要就是兩個

1. 我要拿到舊資料
2. 我要可以改舊資料

但是這一題要和`router`去做搭配
所以我先去`App.js`建立了這個`Route`

```javascript=
 <Route exact path="/post/edit/:id" component={Edit} />
```
然後建立了`<Edit />` component

原本我想錯了, 想說我要拿`<post>`的格式去套. 
但是我這樣拿不到舊資料, 於是我在youtube上下個關鍵字, `react edit api`

[影片支援](https://www.youtube.com/watch?v=yN5qKqLDlpM)

`edit`其實是拿`Share`去套的, 因為這樣可以拿到原本的`value`
一樣啊, 我在`edit`, 也需要`const { author, title, body } = this.state`

但是`edit`需要多一個`id`, 因為我還是要拿到單頁的各種value

```javascript=
class Edit extends Component {
    constructor(props) {
        super(props)
		//state下在edit裡面
        this.state = {
            id: '',
            author: '',
            title: '',
            body: ''
        }
    }

//拿到原本的舊資料
componentDidMount() {
    const postId = this.props.match.params.id
    getSinglePost(postId)
        .then(resp => {
            this.setState({
                id: resp.data.id,
                author: resp.data.author,
                title: resp.data.title,
                body: resp.data.body
            })
        })
        .catch(error => console.log(error))
}

    //這邊已經可以拿到變更後的值. 
    handleChange = (e) => {
        const { author, title, body } = this.state
        this.setState({
            [e.target.name]: e.target.value
        })
    }


    onConfirm = () => {
		//透過edit把值變更
        const postId = this.props.match.params.id
        const { author, title, body } = this.state
        editPost(postId, author, title, body).then(response => {
            this.props.history.push('/post')
        })
        this.setState({
            author: '',
            title: '',
            body: ''
        })
    }
```
這也寫真的合情合理

呼應我一開始說的
1. 我要拿到舊資料 => 透過getSinglePost來拿 => 顯示在該在的位置上 => 因為有設定value

2. 我要可以改舊資料 => 在component裡面設定state=> handleChange改變state => 透過edit的api
把資料最後送出去. 


這個練習蠻棒的!!
