รายละเอียดสำหรับเรียนรู้ React ปี 2020-2023 โดยโค้ชพล ดูหลักสูตรได้ที่ https://www.nextflow.in.th/react-training
redux-thunk
จะเป็นส่วนที่ทำงานแบบ Asynchronous ได้redux-logger
เป็นกลไก log console ของ reduxnpm i redux-thunk redux-logger
สร้างไฟล์ public\branch.json
{
"headquarterId" : 1,
"branches": [
{
"id": 1,
"name": "Silom",
"position": {
"lat": 13.7200452,
"lng": 100.5135078
},
"chartData": {
"chartField": ["Month","Amount"],
"datas": [
{ "month": "February", "amount": 10392 },
{ "month": "March", "amount": 18239 },
{ "month": "April", "amount": 14290 },
{ "month": "May", "amount": 23912 },
{ "month": "June", "amount": 26167 },
{ "month": "July", "amount": 28199 }
]
}
},
{
"id": 2,
"name": "Cholburi",
"position": {
"lat": 13.1247584,
"lng": 100.9133127
},
"chartData": {
"chartField": ["Month","Amount"],
"datas": [
{ "month": "February", "amount": 70032 },
{ "month": "March", "amount": 54789 },
{ "month": "April", "amount": 62789 },
{ "month": "May", "amount": 89272 },
{ "month": "June", "amount": 100328 },
{ "month": "July", "amount": 128903 }
]
}
}
]
}
จำที่พลบอกว่า store เหมือนเป็นตัวเชื่อมทุกอย่างเข้าด้วยกันได้ไหม?
เราจะเอา thunk และ logger มาใส่ในส่วนที่เรียกว่า applyMiddleware
ครับ
import { createStore, applyMiddleware } from 'redux';
import dashboardReducer from "./dashboard.reducer";
import thunk from 'redux-thunk';
import { logger } from 'redux-logger';
export default function configureStore() {
const store = createStore(
dashboardReducer,
applyMiddleware(thunk, logger)
);
return store;
}
เริ่มแรกเลย เราจะไปที่ src/index.js
และย้าย Redux Provider มาไว้ที่นี่แทน
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Provider} from 'react-redux'
import configureStore from "./redux/store";
const store = configureStore();
ReactDOM.render((
<Provider store={store}><App/></Provider>
), document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls. Learn
// more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
จากนั้น เราจะปรับ App.js
ให้เป็น Class component
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import HeaderBar from './components/HeaderBar';
import MapBranch from './components/MapBranch';
import StatChart from './components/StatChart';
import { Layout, Menu, Row, Col } from 'antd';
const { Header, Content, Footer } = Layout;
class App extends Component {
render() {
return (
<div>
<Layout className="layout">
<HeaderBar />
<Content style=>
<div
style=>
<Row gutter={16}>
<Col span={12}><MapBranch /></Col>
<Col span={12}><StatChart/></Col>
</Row>
</div>
</Content>
<Footer style=>React Redux Workshop ©2012-2019 Created by Nextflow.in.th</Footer>
</Layout>,
</div>
);
}
}
export default App;
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { connect } from 'react-redux';
import HeaderBar from './components/HeaderBar';
import MapBranch from './components/MapBranch';
import StatChart from './components/StatChart';
import { Layout, Menu, Row, Col } from 'antd';
const { Header, Content, Footer } = Layout;
class App extends Component {
render() {
return (
<div>
<Layout className="layout">
<HeaderBar />
<Content style=>
<div
style=>
<Row gutter={16}>
<Col span={12}><MapBranch /></Col>
<Col span={12}><StatChart/></Col>
</Row>
</div>
</Content>
<Footer style=>React Redux Workshop ©2012-2019 Created by Nextflow.in.th</Footer>
</Layout>,
</div>
);
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = {
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
เปิดไฟล์ src/redux/actions.js
const ActionTypes = {
SHOW_BRANCH_DATA: "SHOW_BRANCH_DATA",
REQUEST_INIT_DATA: "REQUEST_INIT_DATA"
}
const showBranchData = (branchId) => ({
type: ActionTypes.SHOW_BRANCH_DATA,
payload: branchId
})
const requestInitData = () => {
return async (dispatch) => {
try {
const success = await fetch('https://www.nextflow.in.th/api/branch-info/branch.json');
console.log(success);
console.log('load data success');
return success;
} catch (error) {
console.log(`Load data error: ${error}`);
return error;
}
}
}
export default {
requestInitData,
showBranchData,
ActionTypes
}
เราสามารถใช้ method componentDidMount()
ตอนที่มีการแสดง App Component ได้
class App extends Component {
componentDidMount() {
this.props.initData();
}
โดยเราทำการผูก action เข้ากับ props ในส่วนของ mapDispatchToProps
const mapDispatchToProps = dispatch => {
return {
initData: () => dispatch(actions.requestInitData())
}
}
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { connect } from 'react-redux';
import HeaderBar from './components/HeaderBar';
import MapBranch from './components/MapBranch';
import StatChart from './components/StatChart';
import { Layout, Menu, Row, Col } from 'antd';
import actions from './redux/actions';
const { Header, Content, Footer } = Layout;
class App extends Component {
componentDidMount() {
this.props.initData();
}
render() {
return (
<div>
<Layout className="layout">
<HeaderBar />
<Content style=>
<div
style=>
<Row gutter={16}>
<Col span={12}><MapBranch /></Col>
<Col span={12}><StatChart/></Col>
</Row>
</div>
</Content>
<Footer style=>React Redux Workshop ©2012-2019 Created by Nextflow.in.th</Footer>
</Layout>,
</div>
);
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = dispatch => {
return {
initData: () => dispatch(actions.requestInitData())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);