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