react-redux

空谷足音 2019-12-16

 目录:

1、

2、

3、

1、一个demo,纯react实现 

效果:

react-redux

 项目结构:

react-redux

index.js

import React from ‘react‘
import ReactDOM from ‘react-dom‘

import App from ‘./components/app.jsx‘

ReactDOM.render(<App></App>, document.getElementById(‘app‘))

app.jsx

import React from ‘react‘

export default class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            count: 0
        }
    }
    render() {
        return (
            <div>
                <p>click {this.state.count} times</p>
                <select ref={select => this.select = select}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                &nbsp;
                <button onClick={this.increment}>+</button>&nbsp;
                <button onClick={this.decrement}>-</button>
            </div>
        )
    }

    increment = () => {
        const num = this.select.value * 1
        const { count } = this.state
        this.setState({ count: count + num })
    }

    decrement = () => {
        const num = this.select.value * 1
        const { count } = this.state
        this.setState({ count: count - num })
    }

}

2、引入redux的实现 

 下载依赖

npm install --save redux

redux工作流程

react-redux

   redux核心API

使用redux改造后,项目结构:

react-redux

   index.js

import React from ‘react‘
import ReactDOM from ‘react-dom‘
import { createStore } from ‘redux‘

import App from ‘./components/app.jsx‘
import { counter } from ‘./redux/reducers.js‘

// 根据counter函数创建store对象
const store = createStore(counter)

// 定义渲染根组件标签的函数
const render = () => {
    ReactDOM.render(
        <App store={store} />,
        document.getElementById(‘root‘)
    )
}
// 初始化渲染
render()

// 注册(订阅)监听, 一旦状态发生改变, 自动重新渲染
store.subscribe(render)

app.jsx

import React from ‘react‘
import PropTypes from ‘prop-types‘
import * as actions from ‘../redux/actions.js‘

export default class App extends React.Component {

    static propTypes = {
        store: PropTypes.object.isRequired,
    }

    render() {
        return (
            <div>
                <p>click {this.props.store.getState()} times</p>
                <select ref={select => this.select = select}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                &nbsp;
                <button onClick={this.increment}>+</button>&nbsp;
                <button onClick={this.decrement}>-</button>
            </div>
        )
    }

    increment = () => {
        const number = this.select.value * 1
        this.props.store.dispatch(actions.increment(number))
    }

    decrement = () => {
        const number = this.select.value * 1
        this.props.store.dispatch(actions.decrement(number))
    }

}

action-types.js

// action对象的type常量名称模块
export const INCREMENT = ‘increment‘
export const DECREMENT = ‘decrement‘

action.js

// action creator模块
import { INCREMENT, DECREMENT } from ‘./action-types.js‘

export const increment = number => ({ type: INCREMENT, number })
export const decrement = number => ({ type: DECREMENT, number })

reducers.js

// 根据旧state和指定action, 处理返回一个新的state
import { INCREMENT, DECREMENT } from ‘./action-types.js‘

export function counter(state = 0, action) {
    console.log(‘counter‘, state, action)
    switch (action.type) {
        case INCREMENT:
            return state + action.number
        case DECREMENT:
            return state - action.number
        default:
            return state
    }
}

3、引入redux + react-redux 

React-Redux的思想:将所有组件分成两大类

1) UI组件
    a.只负责 UI 的呈现,不带有任何业务逻辑
    b.通过props接收数据(一般数据和函数)
    c.不使用任何 Redux 的 API
    d.一般保存在components文件夹下
2) 容器组件
    a.负责管理数据和业务逻辑,不负责UI的呈现
    b.使用 Redux 的 API
    c.一般保存在containers文件夹下

改造后项目结构:

react-redux

   index.js

import React from ‘react‘
import ReactDOM from ‘react-dom‘
import { Provider } from ‘react-redux‘

import App from ‘./containters/app.jsx‘
import store from ‘./redux/store.js‘


ReactDOM.render(
    (<Provider store={store}>
        <App />
    </Provider>),
    document.getElementById(‘root‘)
)

app.jsx

/*
包含Counter组件的容器组件
 */
import React from ‘react‘
// 引入连接函数
import { connect } from ‘react-redux‘
// 引入action函数
import { increment, decrement } from ‘../redux/actions.js‘
import Counter from ‘../components/counter.jsx‘

// 向外暴露连接App组件的包装组件
export default connect(
    state => ({ count: state }),
    { increment, decrement }
)(Counter)

counter.jsx

/*
UI组件: 不包含任何redux API
 */
import React from ‘react‘
import PropTypes from ‘prop-types‘

export default class Counter extends React.Component {

    static propTypes = {
        count: PropTypes.number.isRequired,
        increment: PropTypes.func.isRequired,
        decrement: PropTypes.func.isRequired
    }

    render() {
        return (
            <div>
                <p>click {this.props.count} times</p>
                <select ref={select => this.select = select}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                &nbsp;
                <button onClick={this.increment}>+</button>&nbsp;
                <button onClick={this.decrement}>-</button>
            </div>
        )
    }

    increment = () => {
        const number = this.select.value * 1
        this.props.increment(number)
    }

    decrement = () => {
        const number = this.select.value * 1
        this.props.decrement(number)
    }

}

action-types.js

// action对象的type常量名称模块
export const INCREMENT = ‘increment‘
export const DECREMENT = ‘decrement‘

actions.js

// action creator模块
import { INCREMENT, DECREMENT } from ‘./action-types.js‘

export const increment = number => ({ type: INCREMENT, number })
export const decrement = number => ({ type: DECREMENT, number })

reducers.js

// 根据旧state和指定action, 处理返回一个新的state
import { INCREMENT, DECREMENT } from ‘./action-types.js‘

export function counter(state = 0, action) {
    console.log(‘counter‘, state, action)
    switch (action.type) {
        case INCREMENT:
            return state + action.number
        case DECREMENT:
            return state - action.number
        default:
            return state
    }
}

store.js

import { createStore } from ‘redux‘
import { counter } from ‘./reducers.js‘

// 根据counter函数创建store对象
const store = createStore(counter)

export default store

相关推荐

jiangcs0 / 0评论 2020-04-19

空谷足音 / 0评论 2019-04-28