美文网首页
如何使用redux

如何使用redux

作者: 薄荷加冰 | 来源:发表于2019-07-28 16:30 被阅读0次

    1. redux如何使用
    Redux是一个状态管理工具,在react-redux中有一个顶层组件Provider,里面有一个属性store,这个store是全局的,每个组件都可以访问,每个组件中在react-redux中 有一个connect并与全局的store进行连接,action中dispatch用于触发reducers函数,reducers接受两个参数,一个state,一个action,返回新的state,从而进行数据更新。
    例子:使用redux实现一个简单的todolist的代码。
    (1) 首先创建store文件夹,下面的index.js,把store当作一个仓库,用来存储数据。

    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; 
    
    

    (2) 在src下创建todolist.js

    import 'antd/dist/antd.css';
    
    import store from './store/index.js';
    import TodoListUI from './TodoListUI.js'
    import { getInputChangeAction, getAddItemAction, getDeleteItemAction } from './store/actionCreators.js'
    
    class TodoList extends Component {
        constructor (props) {
            super(props);
            this.state = store.getState();
            this.handleInputChange = this.handleInputChange.bind(this);
            this.handleStoreChange = this.handleStoreChange.bind(this);
            this.handleBtnClick = this.handleBtnClick.bind(this);
            this.handelItemDelete = this.handelItemDelete.bind(this);
            store.subscribe(this.handleStoreChange)
        }
        render() {
            return (
                <TodoListUI
                 inputValue = {this.state.inputValue}
                 handleInputChange = {this.handleInputChange}
                 handleBtnClick = {this.handleBtnClick}
                 handelItemDelete = {this.handelItemDelete}
                 list = {this.state.list}
                 ></TodoListUI>
            )
        }
        handleInputChange(e) {
            // const action = {
            //     type: CHANGE_INPUT_VALUE,
            //     value: e.target.value
            //}
            const action = getInputChangeAction(e.target.value)
            store.dispatch(action)
        }
        handleStoreChange() {
            this.setState(store.getState(
    
            ))
        }
        handleBtnClick() {
            // const action = {
            //     type: ADD_TODO_ITEM
            // }
            const action = getAddItemAction();
            store.dispatch(action)
        }
        handelItemDelete(index) {
            // const action = {
            //     type: DELETE_TODO_ITEM,
            //     index
            // }
            const action = getDeleteItemAction(index)
            store.dispatch(action)
        }
    }
    
    export default TodoList;
    

    (3) 在src下创建todoitem.js

    import PropTypes from 'prop-types';
    class TodoItem extends Component {
        constructor (props) {
            super(props);
            //当组件state,props 的发生变化时,render函数就会重新执行
            this.handleClick = this.handleClick.bind(this); //改变this指向
        }
        render() {
            const {content, test} = this.props;
            return <div onClick = {this.handleClick}>
                {test}_{content}
            </div>
        }
        //shanchu 子组件调用父组件的方法 去删除父组件的内容
        handleClick () {
            //alert(this.props.index);
            //在子组件里面调用父组件的方法 调用父组件传递给子组件的方法;
            const {deleteitem, index} = this.props;
            deleteitem(index);
    
        }
    }
    //对类型做校验 要求父组件给子组件传值的时候 值得类型式什么
    TodoItem.propTypes = {
        test: PropTypes.string.isRequired,
        content: PropTypes.string,
        handleClick: PropTypes.func,
        index: PropTypes.number
    } 
    // oneOfType 或者
    
    //如果父组件没有向子组件传值,给的默认值
    TodoItem.defaultProps = {
        test: 'hellow world'
    }
    export default TodoItem;
    

    (4)在src下面创建TodoListUI.js,通过antd引入ui组件。

    import { Input, Button, List } from 'antd';
    const TodoListUI = (props) => {
        return (
                <div style = {{marginTop: 10, marginLeft: 10}}>
                <div>
                    <Input 
                    value = {props.inputValue}
                    placeholder = 'todo indo'
                    style = {{width: 300,marginRight: 10}}
                    onChange = {props.handleInputChange}
                    ></Input>
                    <Button type='提交' onClick = {props.handleBtnClick}>提交</Button>
                </div>
                <List bordered
                    dataSource = {props.list}
                    style = {{width: 300, marginTop: 10}}
                    renderItem = {(item, index) => (<List.Item 
                    onClick = {() => {
                        props.handelItemDelete(index)
                    }}
                    >{item}</List.Item>)}
                ></List>
            </div>
            )
    }
    export default TodoListUI;
    

    (5) 在store下创建actionCreators.js
    通过判断actionType的type值,处理事件的方法

    
    export const getInputChangeAction = (value) => ({
        type: CHANGE_INPUT_VALUE,
        value
    })
    export const getAddItemAction = (value) => ({
        type: ADD_TODO_ITEM,
        value
    })
    export const getDeleteItemAction = (index) => ({
        type: DELETE_TODO_ITEM,
        index
    })
    

    (6)在store下创建actionType.js

    export const ADD_TODO_ITEM = 'add_todo_item';
    export const DELETE_TODO_ITEM = 'delete_todo_item';
    

    (7)在store下创建reducer.js

    const defaultState = {
        inputValue: '123',
        list: [1, 2] //默认数据
    }
    
    //reducer可以接收state但是不能修改state
    export default (state = defaultState, action) => {
        if (action.type === 'change_input_value') {
            const newState = JSON.parse(JSON.stringify(state));
            newState.inputValue = action.value;
            return newState;
        }
        if (action.type === 'add_todo_item') {
            const newState = JSON.parse(JSON.stringify(state));
            newState.list.push(newState.inputValue);
            newState.inputValue = ''
            return newState;
        }
        if (action.type === 'delete_todo_item') {
            const newState = JSON.parse(JSON.stringify(state));
            newState.list.splice(action.index, 1);
            return newState;
        }
        return state;
    }
    

    最后在index.js中可以引入我们的todolist.js的组件

    import ReactDOM from 'react-dom';
    import Todolist from '../src/Todolist.js';
    import * as serviceWorker from './serviceWorker';
    
    //组件的拆分
    ReactDOM.render( < Todolist / > , document.getElementById('root'));
    serviceWorker.unregister(); 
    

    2. redux-saga如何使用
    Effect 是一个javaScript对象,可以通过yield传达给sagaMiddleware进行执行,我们用了redux-saga,所有的effect 都必须被yield才会执行eg :yield call(fetch, url)Call:call 主要是触发某个动作Put:触发某个action,作用和dispatch相同:Select:作用和redux thunk 中的getstate相同。可以通过yield select 来获取当前state中的某些字段Take:等待dispatch匹配某个action。

    相关文章

      网友评论

          本文标题:如何使用redux

          本文链接:https://www.haomeiwen.com/subject/ewpslctx.html