React Redux写一个todoList

1,481 阅读3分钟

前言

之前写了 Redux 相关的实战,很多人说:啊!Up主这个你涉及的知识点太多了呀,我学不会呀,有没有简单一点的呀?

我想了想,确实一个知识点就不要穿插其他难懂的知识点了,这样对小白不友好,那我就给大伙写用最原始的 html、css、jsredux 的来写一个简易版的todolist吧,保证你立马上手redux

效果图

TodoList 这个效果的功能点有:

  1. input 框输入点击+将添加到下方
  2. 点击下方某 item 可以将其删除

准备

  1. 在你的开发环境添加 reactredux
    • 这个你不会的话就去安装一个npm或者yarn,用npm或yarn命令来安装。
  2. index.js 主文件,入口
  3. TodoList.js ` 组件文件,实现
  4. store/index.js 返回 store ,你可以把它想象为银行存款会影响视图更新(我也忘记从哪里看的这个比喻的,我觉得还挺好理解的)
  5. store/reducer.js 银行的计算器,处理数据。根据 action.type 你要做啥操作,()=> newState计算出的钱💰 会改变原来的存款 💰

源码

index.js

通过 Providerstore 注射进 TodoList 组件

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
import {Provider} from 'react-redux';//提供器
import store from './store'
import './index.css';

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

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

TodoList.js

import React from "react";
import { connect } from "react-redux"; //链接器


const TodoList = (props) => {
  let { inputValue,list,inputChange,clickBtn,deletItem} = props;
  return (
    <div className='content'>
      <div className='todoListDiv'>
        <div className='inputDiv'>
           <input value={inputValue} onChange={inputChange} />
           <button onClick={clickBtn}></button> 
        </div>
        <div className='listDiv'>
          <ul>
            {list.map((item, index) => {
              return <li key={index} onClick={deletItem}>
                {item}
              </li>;
            })}
          </ul>
        </div>
      </div>
    </div>
  );
};

//静态数据
const stateToProps = (state) => {
  return {
    inputValue: state.inputValue,
    list: state.list,
  };
};

//方法
const dispatchToProps = (dispatch) => {
  return {
    inputChange(e) {
      let action = {
        type: "change_input",
        value: e.target.value,
      };
      dispatch(action);
    },
    clickBtn() {
      let action = {
        type: "add_item",
      };
      dispatch(action);
    },
    deletItem() {
      let action = {
        type: "delete_item",
      };
      dispatch(action);
    },
  };
};

export default connect(stateToProps, dispatchToProps)(TodoList);

通过 connect 可以在 stateToProps 获得 state 的值并把它注射到 props 里,可以看到在 props 可以获得 inputValue list 这两个值。

同理 dispatchToProps ,这些方法 inputChange,clickBtn,deletItem 也可以在 props 获取,里面写的 dispatch(action) 对应 reducer.js 文件:

reducer.js

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


export default (state = defaultState,action)=>{
    if(action.type === 'change_input'){
        let newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
    }

    if(action.type === 'add_item'){
        let newState = JSON.parse(JSON.stringify(state))
        newState.list.push(newState.inputValue)
        newState.inputValue=''
        return newState
    }
    return state
}

通过 action.type 识别要做什么操作,会更新 store

store.js

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

const store = createStore(reducer)

export default store

提供 store

inex.css

.content{
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    background-image: linear-gradient( 
    62deg, rgb(135 94 215 / 48%) 13%, rgb(161 122 255 / 29%) 4%), linear-gradient( 
    44deg, rgba(0, 43, 99, 0.0792209024) 39%, rgb(242 140 206 / 29%) 18%), linear-gradient( 
    118deg, rgba(84, 202, 242, 0.0315299727) 40%, rgba(215, 152, 218, 0.5) 54%), linear-gradient( 
    58deg, rgba(246, 171, 236, 0.161) 83%, rgba(240, 193, 230, 0.909) 23%);
}
.todoListDiv{
    border-radius: 8px;
    width: 480px;
    background-color: #10101d;
    padding: 24px;
}
input{
    width: 100%;
    padding: 0 4px;
    border: none;
    border-bottom: 1px solid #fff;
    background-color: transparent;
    color: #fff;
}
button{
    width: 44px;
    height: 41px;
    border-radius: 50%;
    background-size: 44px;
    background-position: center;
    background-repeat: no-repeat;
    background-image:url('add.svg')
}
.inputDiv{
    display: flex;
}
ul{
    list-style: none;
    padding: 0;
}
li{
    background-color: rgb(136 130 147 / 48%);
    border-radius: 4px;
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    padding: 8px;
    color: #e9e2f5;
}

加上 css 就是加上灵魂

如果说上面是做的剁椒鱼头的鱼头那剁椒和调料就是这道菜的灵魂了

思考时间🤔

虽然是能实现功能,但是我还是希望你能知道这个小功能还是有缺陷的。这里提一下对标实际开发可能存在的问题:

缺少功能

  1. 首先是我故意少写了一个删除的代码逻辑,希望你能看懂自实现这个功能
  2. 可以加定时功能
  3. 可以增加分类
  4. 云存储

优化空间

  1. 现在的值刷新页面就会没有,需要将值存起来
  2. 和实际项目有区别,可以搞个 mock 接口获取数据
  3. React hook 里是不这么写的
  4. 当数据、或者方法很多的时候,我们要怎么写才能让代码可读性更高呢?

结语

非常感谢你看到这,如果觉得不错的话点个赞 ⭐ 吧

今天也是在努力「 变强不变秃 」的 HearLing 呀 ❤️