React + Redux Workshop
tags: f2e
Andy Tsai
Part I
React 介紹
React 實作計數器
Part II
Redux 介紹
計數器加入 Redux
StarterKit
npm install
npm start
環境介紹
ES6 + webpack + React + BABEL core
ES6(ECMAScript 2015)
Netscape公司將Javascript交給國際標準化組織ECMA,希望這種語言可以成國際標準
標準委員會最終決定,標準在每年6月正式發表一次,當作當年的正式版本
ES6於2015年6月發佈,正式名稱就是ECMAScript 2015
Babel
Webpack
前端模組管理和打包工具
將CSS、圖片與其他資源打包
預處理(SASS、JSX、ES6等)檔案
豐富的loader可以使用
Agenda
React 介紹
Virtual DOM
JSX
State Management
Lifecycle
React
React is a declarative, efficient, and flexible JavaScript library for building user interfaces.
React 優點
組件化(Component)設計,利於Reuse
用JSX進行UI設計
使用 Virtual DOM快速進行頁面重繪
Component 就像個狀態機(State Machine),而且也有生命週期(Life Cycle)
一律重繪(Always Redraw)和單向資料流
what is DOM
(Document Object Model)
This is HTML
< table>
< tbody>
< tr>
< td> Shady Grove< / td>
< td> Aeolian< / td>
< / tr>
< tr>
< td> Over the River, Charlie< / td>
< td> Dorian< / td>
< / tr>
< / tbody>
< / table>
and this is DOM
Browser layout
var h1 = element1.clientHeight ;
element1.style .height = (h1 * 2 ) + 'px' ;
var h2 = element2.clientHeight ;
element2.style .height = (h2 * 2 ) + 'px' ;
var h3 = element3.clientHeight ;
element3.style .height = (h3 * 2 ) + 'px' ;
Browser layout
Even load element from DOM will cause layout event.
Vitrual DOM working flow
React Component
class Hello extends React .Component {
constructor(props){
super (props)
}
render() {
return (<div>Hello World </div>)
}
}
JSX
render ( ) {
return
<div className ="divider" >
Label Text<hr />
</div >
}
Plan JS
render : function ( ) {
return
React .DOM .div ({className :"divider" },
"Label Text" ,
React .DOM .hr ()
);
}
Rules
JSX event
class Hello extends React.Component {
handleClick = (event ) => {
};
render ( ) {
return (<div onClick ={this.handleClick} > click me </div > )
}
}
event list
React State Management
props
state
Props
Props
class Child extends React.Component {
render(){
return (
< div>
{
this .props.children.map(
(childName)= > (< div> { childName }< / div> )
)
}
< / div>
)
}
}
class Father extends React.Component {
render(){
let childList = ['Nina' , 'Ona' , 'Bina' ]
return (< Child children= {childList} / > )
}
}
ReactDOM.render(< Father/ > , document.getElementById('app' ))
State
整個Component當作一個狀態機(State Machine)
一開始有個初始狀態,隨著使用者的互動會讓狀態改變,此時就會觸發讓 UI 重繪 (render)
使用this.setState()更新state
State
class TestStateComponent extends React.Component {
constructor () {
super ();
this .state = {
name : 'jack'
};
}
clickComp = () => {
let new_state = {
name : this .state .name + 'click'
}
this .setState (new_state);
};
render () {
return (
<div className ="teststate-component" onClick ={this.clickComp} >
{this.state.name}
</div >
);
}
}
React Component lifecycle
class BookNormalComponent extends React.Component {
componentDidMount ( ){
console .log ('component first show in screen' );
}
render ( ) {
return (
<div className ="booknormal-component" >
Very Good
</div >
)
}
}
React Component Generator
React 實作計數器
Agenda
Why Redux
單向資料流
三大原則
Action
Reducer
Store
Redux 介紹
Why Redux
網站需要管理比任何時候都要多的state(狀態)
state在什麼時候,由於什麼原因,如何變化已經不受控制
React專注於View,卻沒有好的機制管理state
Redux就是讓管理state變得可預測
單向資料流
三大原則
Single source of truth (store)
State is read-only (action)
Changes are made with pure functions (reducer)
1. Single source of truth (store)
整個網站的state存在一個store裡
儲存state
{
visibilityFilter: 'SHOW_ALL' ,
todos: [
{
text: 'Consider using Redux' ,
completed: true,
},
{
text: 'Keep all state in a single tree' ,
completed: false
}
]
}
2. State is read-only (action)
唯一改變state的方法就是發送action
傳送資料
store.dispatch({
type : 'ADD_TODO' ,
text
})
3. Changes are made with pure functions (reducer)
Reducer是pure function,接收舊的state和action,回傳新的state
撰寫商業邏輯的地方
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state ,
{
text: action.text,
completed: false
}
]
default :
return state
}
}
pure function
var xs = [1 , 2 , 3 , 4 , 5 ];
xs.slice(0 , 3 );
xs.slice(0 , 3 );
xs.slice(0 , 3 );
impure function
xs.splice(0 , 3 );
xs.splice(0 , 3 );
xs.splice(0 , 3 );
Action
Action 從網站傳送資料至store
它是更新store的唯一來源
使用store.dispatch()傳送資料
{
type : ADD_TODO ,
text
}
Action creator
Action creators 是產生action的function
function addTodo (text) {
return {
type : ADD_TODO,
text
}
}
Reducer
Action 只負責傳送資料,卻未進行state修改
Reducer就是負責撰寫邏輯並修改state的地方,最後回傳新的state
不該在Reducer內做的事情
修改傳入的參數
執行API呼叫、Route跳轉
呼叫impure function, 如Date.now() or Math.random()
Handling Actions
function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state ,
{
text: action.text,
completed: false
}
]
default :
return state
}
}
Store
Redux只有一個store
使用store.getState()取得state
使用dipatch(action)更新state
使用subscribe(listener)註冊listener
createStore, combineReducers
import { createStore, combineReducers } from 'redux'
import counter from 'counterReducer' ;
import todos from 'todosReducer' ;
const rootReducer = combineReducers ({
counter,
todos
})
export default createStore (rootReducer)
dispatch
store.dispatch(addTodo('todo1' ))
store.dispatch(addTodo('todo2' ))
store.dispatch(addTodo('todo3' ))
Redux 四步驟
store.dispatch(action)
reducer return new state
combine multiple reducers into a single state tree (combineReducers)
Every listener registered with store.subscribe(listener) will now be invoked. listeners may call store.getState() to get the current state (connect -> react-redux)
計數器加入 Redux
npm install - - save redux react- redux
資料流
Presentational Components (Dumb Component)
Container Components (Smart Container)
作用
畫面如何呈現
更新狀態
使用Redux
No
Yes
資料來源
Props
Redux state
修改資料
從props呼叫callback
Dispatch Redux actions
Container and Component
Create Container and Component
Create Container
+ containers
- Panel.js
Create Component
+ components
- Btn.js
- Show.js
Create Action
Create Action
+ actions
- counterAction.js
Create Reducer
Create Reducer
+ reducers
- counterReducer.js
Create Store
Create Store
+ store
- configureStore.js
Redux與View連接
connect
mapStateToProps() 將Redux store state放到props
mapDispatchToProps() 接收dispatch()並將callback放到props
根據每個container放入所需state及action
export default connect(mapStateToProps , mapDispatchToProps )(Panel );
curry
var add = function (x ) {
return function (y ) {
return x + y;
};
};
add(1 )(10 );
mapStateToProps
const mapStateToProps = (state ) => {
return {
counterReducer: state .counterReducer
}
}
mapDispatchToProps
const mapDispatchToProps = (dispatch) => {
return {
counterAction: bindActionCreators(counterAction, dispatch)
}
}
Provider
使用一個特殊的React Redux Component叫做 <Provider>,它可以魔法般的讓全部container取得store
只需要在root component使用一次就好
< Provider store= {configureStore}>
< Panel / >
< / Provider>
Resume presentation
React + Redux Workshop tags: f2e Andy Tsai 線上ReactJS讀書會
{"metaMigratedAt":"2023-06-14T12:12:53.772Z","metaMigratedFrom":"Content","title":"React + Redux Workshop","breaks":true,"contributors":"[{\"id\":\"e23ef62f-a089-4a28-8ce7-817212441f68\",\"add\":20,\"del\":0}]"}