Redux 安裝及使用

安裝

yarn add redux
或者
npm install --save-dev redux

創建目錄

// /src/store/actionCreators.js
import { CHANGINPUT, ADDBBIMN, DELEMTITEM } from './actionTypes'
export const changInput = (value) => ({
    type: CHANGINPUT,
    value: value
})
export const addbindCheng = () => ({
    type: ADDBBIMN,
})
export const deleteItemCheng = (index) => ({
    type: DELEMTITEM,
    value:index
})
// /src/store/actionTypes.js
export const CHANGINPUT = 'CHANGINPUT'
export const ADDBBIMN = 'Add_bbimn'
export const DELEMTITEM = 'DelemtItem'
// /src/store/
// /src/store/index.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer,  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

export default store
// /src/store/reducer.js
import { CHANGINPUT, ADDBBIMN, DELEMTITEM } from './actionTypes'
const defaultStatus = {
    inputValue: '這是屬性',
    list: [
        '1121',
        '22222',
        '33333',
        '44444',
        '55555'
    ]
}
//Reducer 必須是純函數 不能調用ajax 等等
export default (state = defaultStatus, action) => {
    console.log(state, action)
    if(action.type === CHANGINPUT) {
        // Reducer 裏只能接受 state 不能改變state
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.inputValue = action.value
        return newStade
    }
    if (action.type === ADDBBIMN) {
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.list.push(newStade.inputValue)
        return newStade
    }
    if(action.type === DELEMTITEM) {
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.list.splice(action.value, 1)
        return newStade
    }
    return state
}
// /src/TodoList.jsx 
import React, { Component } from 'react'
import store from './store'
import { CHANGINPUT, ADDBBIMN, DELEMTITEM } from './store/actionTypes'
import { changInput, addbindCheng, deleteItemCheng} from './store/actionCreators'
import TodoListUI from './TodoListUI'
import axios from 'axios'
export default class TodoList extends Component {
    constructor(props){
        super(props)
        console.log(store.getState())  // 輸入值
        this.state = store.getState()
        this.storeChange = this.storeChange.bind(this)
        // 如果不加這個 綁定value(有坑)value  數據不會發生變化
        store.subscribe(this.storeChange)  
        this.addbind = this.addbind.bind(this)
        this.deleteItem = this.deleteItem.bind(this)
    }
    componentDidMount() {
        axios.get('http://mock-api.com/jzAV0Ggk.mock/Updeat').then((datas) => {
            // JSON.parse(data.data)
            console.log(datas.data)
        })
    }
    changeOn(e) {
        // console.log(e.target.value)
        const action = changInput(e.target.value)
        store.dispatch(action)
    }
    storeChange(){
        this.setState(store.getState())
    }
    addbind() {
        const action = addbindCheng()
        store.dispatch(action)
    }
    deleteItem(index) {
        console.log(index)
        // const action = {
        //     type: DELEMTITEM,
        //     value: index
        // }
        const action = deleteItemCheng(index)
        store.dispatch(action)
    }
    render() {
        return (
            <TodoListUI
                inputValue= {this.state.inputValue}
                addbind= {this.addbind}
                list = { this.state.list }
                deleteItem={this.deleteItem}
            />
        )
    }
}
// /src/TodoListUI.jsx
import React, { Component } from 'react'
import { Button, Input, List } from 'antd';
// UI 改成無狀態組件性能更高

const TodoListUI = (props) => {
    return (
        <div style={{marginLeft:'20px',marginTop:'20px'}}>
            <div>
                <Input placeholder="請選擇" value={props.inputValue} style={{width:'250px'}} onChange={props.changeOn}></Input>
                <Button type="primary" style={{marginLeft:'20px'}} onClick={props.addbind}>增加</Button>
            </div>
            <div style={{width:'300px'}}>
                <List
                    bordered
                    dataSource={props.list}
                    renderItem={(item, index)=>(<List.Item onClick={() => props.deleteItem(index)}>{item}</List.Item>)}
                />
            </div>
        </div>
    )
}

/* class TodoListUI extends Component {
    render() {
        return (
            <div style={{marginLeft:'20px',marginTop:'20px'}}>
                <div>
                    <Input placeholder="請選擇" value={this.props.inputValue} style={{width:'250px'}} onChange={this.props.changeOn}></Input>
                    <Button type="primary" style={{marginLeft:'20px'}} onClick={this.props.addbind}>增加</Button>
                </div>
                <div style={{width:'300px'}}>
                    <List
                        bordered
                        dataSource={this.props.list}
                        renderItem={(item, index)=>(<List.Item onClick={(index) => { this.props.deleteItem(index)}}>{item}</List.Item>)}
                    />
                </div>
            </div>
        )
    }
} */
export default TodoListUI;

使用中間件 redux-thun

安裝

yarn add redux-thun

改變 src/store/index.js

/**
 * compose 增強函數
 */
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
const enhancer = composeEnhancers(applyMiddleware(thunk))
const store = createStore(reducer,enhancer)
export default store
// 改變 src/store/actionCreators.js
import { CHANGINPUT, ADDBBIMN, DELEMTITEM, GETLIST} from './actionTypes'
import axios from 'axios'
export const changInput = (value) => ({
    type: CHANGINPUT,
    value: value
})

export const addbindCheng = () => ({
    type: ADDBBIMN,
})

export const deleteItemCheng = (index) => ({
    type: DELEMTITEM,
    value:index
})
export const getlistAction = (data) =>({
    type: GETLIST,
    value: data
})
// 安裝了 redux-thun 纔可以調用 axios 
export const ListGet = () =>{
    return (dispatch) =>{
        axios.get('http://mock-api.com/jzAV0Ggk.mock/Updeat').then(res=>{
            const data = res.data.split(',')
            const action = getlistAction(data)
            dispatch(action)
        })
    }
}
// // /src/TodoList.jsx  修改
import React, { Component } from 'react'
import store from './store'
import { changInput, addbindCheng, deleteItemCheng, ListGet} from './store/actionCreators'
import TodoListUI from './TodoListUI'

export default class TodoList extends Component {
    constructor(props){
        super(props)
        console.log(store.getState())  // 輸入值
        this.state = store.getState()
        this.storeChange = this.storeChange.bind(this)
        // 如果不加這個 綁定value(有坑)value  數據不會發生變化
        store.subscribe(this.storeChange)  
        this.addbind = this.addbind.bind(this)
        this.deleteItem = this.deleteItem.bind(this)
    }
    componentDidMount() {
    // 如果沒有安裝 redux-thun 執行這句會報錯
        const action = ListGet()
        store.dispatch(action)
    }
    changeOn(e) {
        console.log(e.target.value)
        const action = changInput(e.target.value)
        store.dispatch(action)
    }
    storeChange(){
        this.setState(store.getState())
    }
    addbind() {
        const action = addbindCheng()
        store.dispatch(action)
    }
    deleteItem(index) {
        console.log(index)
        // const action = {
        //     type: DELEMTITEM,
        //     value: index
        // }
        const action = deleteItemCheng(index)
        store.dispatch(action)
    }
    render() {
        return (
            <TodoListUI
                inputValue= {this.state.inputValue}
                changeOn = {this.changeOn}
                addbind= {this.addbind}
                list = { this.state.list }
                deleteItem={this.deleteItem}
            />
        )
    }
}

// /src/store/reducer.js 修改
import { CHANGINPUT, ADDBBIMN, DELEMTITEM, GETLIST } from './actionTypes'
const defaultStatus = {
    inputValue: '這是屬性',
    list: [
        '1121',
        '22222',
        '33333',
        '44444',
        '55555'
    ]
}
//Reducer 必須是純函數 不能調用ajax 等等
export default (state = defaultStatus, action) => {
    console.log(state, action)
    if(action.type === CHANGINPUT) {
        // Reducer 裏只能接受 state 不能改變state
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.inputValue = action.value
        return newStade
    }
    if (action.type === ADDBBIMN) {
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.list.push(newStade.inputValue)
        return newStade
    }
    if(action.type === DELEMTITEM) {
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.list.splice(action.value, 1)
        return newStade
    }
    if (action.type === GETLIST) {
        let newStade = JSON.parse(JSON.stringify(state))
        newStade.list.push(action.value) 
        return newStade
    }
    return state
}
// /src/store//actionTypes.js 修改
export const CHANGINPUT = 'CHANGINPUT'
export const ADDBBIMN = 'Add_bbimn'
export const DELEMTITEM = 'DelemtItem'
export const GETLIST = 'GETLIST'

安裝 redux-saga

redux-saga 是redux的中間件 表示react的中間件

 yarn add redux-saga

react-redux

安裝 必須安裝redux

yarn add redux react-redux

react-redux 例子

創建文件
在這裏插入圖片描述

src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux'
import store from './store'

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));
src/App.js
import React, { Component } from 'react'
import {connect} from 'react-redux'
class App extends Component {
  render() {
    return (
      <div>
        <input value={this.props.inputValue} onChange={this.props.changClick}/>
        <ul>
          {this.props.list.map((item,index)=>{
            return <li key={index} onClick={() => this.props.TonkOnClickDelete(index)}>{item}</li>
          })}
        </ul>
        <button onClick={this.props.tjiaoOclick}>提交</button>
      </div>
    )
  }
}
const mapStateToProps = (state, ownProps) => {
  return {
    inputValue: state.inputValue,
    list: state.list
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    changClick(e) {
      let action = {
        type: 'CRLIOKD',
        value: e.target.value
      }
      dispatch(action)
    },
    tjiaoOclick() {
      let action = {
        type: 'tjiaoOclick',
      }
      dispatch(action)
    },
    TonkOnClickDelete(index){
      let action = {
        type: 'Deletyes',
        value: index
      }
      dispatch(action)
    }
  }
}
export default connect(mapStateToProps,mapDispatchToProps)(App)
src/store/index.js
import { createStore } from 'redux'
import reducer from './reducer'
const actions = createStore(reducer)
export default actions
src/store/reducer.js
const defaultstate = {
    inputValue: '測試數據',
    list: ['212121']
}
export default (state = defaultstate, action) => {
    if(action.type === 'CRLIOKD') {
        let newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
    }
    if (action.type === 'tjiaoOclick') {
        let newState = JSON.parse(JSON.stringify(state))
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }
    if(action.type === 'Deletyes') {
        let newState = JSON.parse(JSON.stringify(state))
        console.log(newState);
        
        newState.list.splice(action.value,1)
        return newState
    }
    return state
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章