react中如何使用redux(react-redux)

首先声明:redux仅仅作为数据层框架,与react没有直接的联系,他可以应用与angular等其他视图层框架,或者直接导入使用

redux核心分为三部分:

store: redux的核心,暴露一些方法:getState()  dispatch()  subscrible(),store在整个应用中是唯一的,并且不能直接被修改,必须通过reduce修改

reduce:指定了应用状态的变化如何响应 actions 并发送到 store 的

action:一个纯JS对象,用来告诉reduce应该如何改变state,多数情况下,会有一个 type 值,且会被定义成字符串常量

实例:

index.js

import { createStore } from 'redux'
import reduce from './reduce'

const store = createStore(reduce, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

export default store

第二个参数

  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

是给Redux开发者工具使用,添加后浏览器图标会激活

reduce.js

const defaultState = {
    data: [
        'Racing car sprays burning fuel into crowd.',
        'Japanese princess to wed commoner.',
        'Australian walks 100km after outback crash.',
        'Man charged over missing wedding girl.',
        'Los Angeles battles huge wildfires.'
    ]
}

export default function reducer(state = defaultState, action){
    switch (action.type) {
        case 'ADD_RECORD':
            return Object.assign(
                {},
                state,
                {
                    data: [...state.data, action.text]
                }
            )
        case 'DEL_RECORD':
            var data = [...state.data]
            data.splice(action.index, 1)
            return Object.assign(
                {}, 
                state,
                {
                    data
                }
            )
        default: 
            return state
    }
}

每当调用store的dispatch方法,会执行reduce函数,reduce要求我们返回一个state,reduce中有以下注意点:

  • 不能直接修改state
  • 不能执行有副作用的操作,如 API 请求和路由跳转
  • 不能调用非纯函数,如 Date.now() 或 Math.random()
  • 大多数情况下,state的数据格式我们可以在初始化的时候可以确定,因此我们可以定义一个默认的

action

export const addRecord = function(text){
    return {
        type: 'ADD_RECORD',
        text
    }
}

export const delRecord = function(index){
    return {
        type: 'DEL_RECORD',
        index
    }
}

在需要修改store状态的组件中触发reduce修改state

import store from './store'
import { addRecord } from './store/action'

class Mycomponent extends Component
{
     ...

    addRecord(){
        //调用 dispatch ,参数为一个 action
        store.dispatch(
            addRecord(this.state.inputVal)
        )
    }

    ...
}

在调用store组件订阅store,实时响应

import store from './store'

class MyList extends React.Component{

    constructor(props){
        super(props)
        this.state = {
            ...store.getState()
        }
        store.subscribe(() => {
            this.setState({
                ...store.getState()
            })
        }) 
    }

    ...
}

reacte-redux

以上这种动手订阅的方式十分繁琐,因此推荐使用专为react打造的第三库 react-redux 去连接redux

使用:

npm install react-redux --save

 在index.js文件中引入 Provider 组件,将它包在最外层,把 store 作为 prop 传入 Provider

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

const Application = (
    <Provider store={store}>
        <App />
    </Provider>
)

ReactDOM.render(Application, document.getElementById('root'));

在应用组件中通过 connect 将组件与 store 关联起来,然后可以通过直接访问 props 的方式访问 store

import React from 'react'
import { connect } from 'react-redux'
import { delRecord } from './store/action'

class MyList extends React.Component{


    render(){
        return (
            <ul className="list-container">
                {this.props.data.map((item, index) => (
                    <li key={index} onClick={() => { this.props.delRecord(index) }}>{item}</li>
                ))}
            </ul>
        )
    }

}

const mapStateToProps = (state) => ({
    ...state
})

const mapDispatchToProps = (dispatch) => ({
    delRecord(index){
        dispatch(delRecord(index))
    }
})

export default connect(mapStateToProps, mapDispatchToProps)(MyList)

其中 connect 是一个高阶函数

第一个参数 

mapStateToProps: 声明将state与props对应的映射关系
mapDispatchToProps: 将需要对store修改操作声明在这个对象中
 

猜你喜欢

转载自www.cnblogs.com/xiaoliwang/p/11211574.html