# [自行分析] 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
把資料最後送出去.
這個練習蠻棒的!!