React & Redux入门教学,什么是Redux

一、什么是Redux

Redux即类Flux的脚本库, 但是它不完全是Flux(Flux是真的繁琐),它包含Action、Action生成器、Store,以及用于修改State的Action对象。

1)State

   在我们不知道Flux和Redux之前,我们想要操作与管理State一般有两种选择:
      1、每个组件单独管理自己的State。
      2、由根节点统一管理,向下传递State。
   这两种方式所暴露出的缺点很明显:
     第一种:State管理杂乱无章,逻辑不清晰,不易于维护。
     第二种:增加代码的逻辑复杂度,增加维护成本。
   Flux和Redux的出现就帮我们完美解决了这些痛点。两者都推荐将State存放尽可能少的几个对象中,这样就降低了我们去维护State的成本,可以将更多的精力放在UI与业务上。

2)Action

   Redux有一个非常重要的规则,应用程序的State应该存放在单个不可变对象中!(State对象无法变更)
   Action是更新Redux应用程序State的唯一方式。Action为我们提供了应该变更哪些内容的指令,说简单点就是我们想让State怎么变化。

3)Reducer

   当我们使用Redux来管理State的时候,我们整个State树都是存储在单个对象中的。一个潜在的问题可能是它的模块化程度不够(如果丧失了模块化的优势,那我就可能放弃学习与使用React了,哈哈。)。Redux是通过函数进行模块化的,他们用来更新指定的State树中的内容,这些函数就被称为Reducer。

3)Store

   Store就是保存应用程序State数据和处理所有State更新的地方。
   Store通过将当前的State和Action传递给单个Reducer来进行State更新。

4)Action生成器

   这个确实没什么说的,Action生成器就是对我们传递的Action参数的一个方法封装,易于使用和维护。


代码

Action & Action生成器

import Constants from "../Constants";
import {v4} from "uuid";

export const AddItem = title => {
    return {
        type: Constants.ADD_ITEM,
        id: v4(),
        title
    }
}

export const RemoveItem = id => {
    return {
        type: Constants.REMOVE_ITEM,
        id
    }
}

Reducer

import Constants from "../Constants";

const item = (state = {}, action) => {
    switch (action.type) {
        case Constants.ADD_ITEM :
            return {
                id: action.id,
                title: action.title
            };
        default :
            return state;
    }
}

export const items = (state = [], action) => {
    switch (action.type) {
        case Constants.ADD_ITEM :
            return [
                ...state,
                item({}, action)
            ];
        case Constants.REMOVE_ITEM :
            return state.filter(i =>
                i.id !== action.id
            )
        default :
            return state;
    }
}

Store

import {createStore, combineReducers} from "redux";
import {items} from "./chapter8-test/reducers";

const store = createStore(combineReducers({items}));

export default store;

Demo代码

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from "./chapter8-test/App";
import store from "./chapter8-test/store";

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

App.js

import React from 'react';
import PropTypes from 'prop-types';
import ItemList from './ItemList';
import AddItemForm from "./AddItemForm";

class App extends React.Component {

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

    static childContextTypes = {
        store: PropTypes.object.isRequired
    }

    getChildContext() {
        return {
            store: this.props.store
        }
    }

    componentWillMount() {
        const { store } = this.props;
        this.unSubscribe = store.subscribe(
            () => this.forceUpdate()
        );
    }

    componentWillUnmount() {
        this.unSubscribe();
    }

    render() {
        return (
            <div>
                <AddItemForm/>
                <ItemList/>
            </div>
        )
    }
}

export default App;

AddItemForm.js

import React from 'react';
import PropTypes from 'prop-types';
import {AddItem} from './actions'

const AddItemForm = (props, {store}) => {

    let title;

    const submit = e => {
        e.preventDefault();
        let addItem = AddItem(title.value);
        store.dispatch(addItem);
        title.value = '';
        title.focus();
    }

    return (
        <form onSubmit={submit}>
            <input type="text"
                   ref={input => title = input}
                   required/>
            <button>ADD</button>
        </form>
    )
}

AddItemForm.contextTypes = {
    store: PropTypes.object
}

export default AddItemForm;

ItemList.js

import React from 'react';
import PropTypes from 'prop-types';
import Item from "./Item";

const ItemList = (props, {store}) => {

    const {items} = store.getState();

    return (
        <ul>
            {items.length === 0 ?
                <span>No Item List. (Add a Item)</span> :
                items.map((item, index) =>
                    <Item key={item.id}
                          {...item}
                    />
                )
            }
        </ul>
    )
}

ItemList.contextTypes = {
    store: PropTypes.object
}

export default ItemList;

Item.js

import React from 'react';
import PropTypes from 'prop-types';
import {RemoveItem} from "./actions";

const Item = (props, {store}) => {

    const {id, title} = props;
    return (
        <li>
            {title}
            <button onClick={() => store.dispatch(RemoveItem(id))}>X</button>
        </li>
    )
}

Item.contextTypes = {
    store: PropTypes.object
}

export default Item;

Constants.js

const Constants = {
    ADD_ITEM: "ADD_ITEM",
    REMOVE_ITEM: "REMOVE_ITEM"
}

export default Constants;

撒花完结

  • 水平有限
  • 能力有限
  • 忘各位大佬勿喷
  • 个人实属太懒,不想写太多字,见谅,见谅
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值