使用React-Redux编写TodoList

准备工作

TodoList组件

import React,{
    
    Component, Fragment} from 'react';
import 'antd/dist/antd.css';
import {
    
     Input,Button,List } from 'antd';
import {
    
     UserOutlined } from '@ant-design/icons';

class TodoList extends Component{
    
    
    render(){
    
    
        return (
            <Fragment>
                <div style={
    
    {
    
    marginTop:'10px',marginLeft:'10px'}}>
                    <Input size="large" placeholder="请输入..." prefix={
    
    <UserOutlined />} 
                        style={
    
    {
    
    width:'300px',marginRight:'10px'}}
                    />
                    <Button type="primary" style={
    
    {
    
    height:'39px'}}>提交</Button>
                </div>
                <List
                    style={
    
    {
    
    width:'300px',marginTop:'10px',marginLeft:'10px'}}
                    size="small"
                    bordered
                    dataSource={
    
    []}
                    renderItem={
    
    (item) => <List.Item>{
    
    item}</List.Item>}
                />
            </Fragment>
        );
    }
}

export default TodoList;

挂载到页面上
在这里插入图片描述

./store/reducer.js
在这里插入图片描述

./store/index.js
在这里插入图片描述
在这里插入图片描述

OK~react-redux开始

首先安装react-redux

在入口文件中引入store以及react-redux的Provider组件

利用为Provider添加store属性之后,Provider下面的所有组件都可以连接store

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

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

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


接下来到TodoList中去通过connect方法按照一定的规则(通过参数传递)连接store

connect方法可传递两个参数:mapStateToProps和mapDispatchToProps

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

mapStateToProps将store中的数据映射到当前组件的props中,这样一来,就可以直接通过this.props.list使用store中的list,inputValue同理

const mapStateToProps=(state)=>{
    
    
    return {
    
    
        value:state.inputValue,
        list:state.list
    }
}

在这里插入图片描述
这样便将store中的数据用到TodoList组件中啦
在这里插入图片描述

但是现在的输入框还不能输入,因此我们要为输入框绑定事件并传递action给store,再给reducer处理

此时事件处理函数就可以放在connect的第二个参数mapDispatchToProps中去写了

它作用是将store.dispatch方法映射到当前组件的props中,这样便可直接使用dispatch参数传递action

const mapDispatchToProps=(dispatch)=>{
    
    
    return {
    
    
        handleChange(e){
    
    
            const action={
    
    
                type:'handle_change',
                value:e.target.value
            }
            dispatch(action);
        }
    }
}

在这里插入图片描述

reducer处理数据

let func=(state=defaultState,action)=>{
    
    
    if(action.type==='handle_change'){
    
    
        const newState=JSON.parse(JSON.stringify(state));
        newState.inputValue=action.value;
        return newState;
    }
    return state;
}

现在输入框便可以输入内容了,这样就无需使用store.subscribe监听store的数据变化再做替换了
在这里插入图片描述
接下来也是同样的道理实现添加和删除功能,就不再多说啦

然后connect方法将todolist这个ui组件和数据和业务逻辑结合,返回的就是一个容器组件了

最后来做一些优化:定义actionTytpes、利用actionCreator统一创建action、对props对象解构赋值、由于组件只有一个render函数,把它处理成一个无状态组件,提升性能

TodoList.js

import React,{
    
    Fragment} from 'react';
import 'antd/dist/antd.css';
import {
    
     Input,Button,List } from 'antd';
import {
    
     UserOutlined } from '@ant-design/icons';
import {
    
    connect} from 'react-redux';
import {
    
    getChangeAction,getClickAction,getRemoveAction} from './store/actionCreator';

let TodoList=(props)=>{
    
    
    const {
    
    value,list,handleChange,handleClick,removeItem} =props;

    return (
        <Fragment>
            <div style={
    
    {
    
    marginTop:'10px',marginLeft:'10px'}}>
                <Input value={
    
    value} size="large" placeholder="请输入..." prefix={
    
    <UserOutlined />} 
                    style={
    
    {
    
    width:'300px',marginRight:'10px'}}
                    onChange={
    
    handleChange}
                />
                <Button type="primary" style={
    
    {
    
    height:'39px'}}
                    onClick={
    
    handleClick}
                >提交</Button>
            </div>
            <List
                style={
    
    {
    
    width:'300px',marginTop:'10px',marginLeft:'10px'}}
                size="small"
                bordered
                dataSource={
    
    list}
                renderItem={
    
    (item,index) => <List.Item onClick={
    
    ()=>{
    
    
                    removeItem(index);
                }}>{
    
    item}</List.Item>}
            />
        </Fragment>
    );
}

const mapStateToProps=(state)=>{
    
    
    return {
    
    
        value:state.inputValue,
        list:state.list
    }
}

const mapDispatchToProps=(dispatch)=>{
    
    
    return {
    
    
        handleChange(e){
    
    
            const action=getChangeAction(e.target.value);
            dispatch(action);
        },

        handleClick(){
    
    
            const action=getClickAction();
            dispatch(action);
        },

        removeItem(index){
    
    
            const action=getRemoveAction(index);
            dispatch(action);
        }
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

reducer.js

import {
    
    HANDLE_CHANGE,HANDLE_CLICK,REMOVE_ITEM} from './actionTypes';

const defaultState={
    
    
    inputValue:'',
    list:['Amethyst']
}

let func=(state=defaultState,action)=>{
    
    
    if(action.type===HANDLE_CHANGE){
    
    
        const newState=JSON.parse(JSON.stringify(state));
        newState.inputValue=action.value;
        return newState;
    }
    if(action.type===HANDLE_CLICK){
    
    
        const newState=JSON.parse(JSON.stringify(state));
        newState.list.push(state.inputValue);
        newState.inputValue='';
        return newState;
    }
    if(action.type===REMOVE_ITEM){
    
    
        const newState=JSON.parse(JSON.stringify(state));
        newState.list.splice(action.value,1);
        return newState;
    }
    return state;
}

export default func;

效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Amethystlry/article/details/113879675