React 之 redux react-redux 使用

注:官方推荐使用 redux-toolkit
这里附上我的另一篇文章:文章链接

1、项目准备

创建项目

npx create-react-app 项目名称

安装 redux

npm install --save redux

安装 react-redux

npm install --save react-redux

2、示例: Todo 列表

入口文件

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { createStore } from "redux";
import App from "./App";
import todoApp from "./reducers";

let store = createStore(todoApp);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

Action

actions/index.js

let nextTodoId = 1;
export const addTodo = (text) => {
  return {
    type: "ADD_TODO",
    id: nextTodoId++,
    text,
  };
};

export const toggleTodo = (id) => {
  return {
    type: "TOGGLE_TODO",
    id,
  };
};

export const setVisibilityFilter = (visible) => {
  return {
    type: "SET_VISIBILITY_FILTER",
    visible,
  };
};

展示组件

components/TodoList.js

import React from "react";

// 展示列表组件

export default function TodoList({ todos, onTodoClick }) {
  return (
    <ul>
      {todos.map((item) => {
        return (
          <li
            key={item.id}
            style={{
              textDecoration: item.completed ? "line-through" : "none",
            }}
            onClick={() => {
              onTodoClick(item.id);
            }}
          >
            {item.text}
          </li>
        );
      })}
    </ul>
  );
}

components/Footer

import React from "react";

// 这里是按钮组件,用来控制显隐

export default function Footer({ hanldeClick }) {
  return (
    <div>
      <button onClick={() => hanldeClick(true)}>显示全部</button>
      <button onClick={() => hanldeClick(false)}>隐藏全部</button>
    </div>
  );
}

容器组件

containers/VisibleTodoList.js

import { connect } from "react-redux";
import TodoList from "../components/TodoList";
import { toggleTodo } from "../actions/index";

// 展示列表组件容器

// mapStateToProps 这个函数把当前 Redux store state 映射到展示组件的 props 中
const mapStateToProps = (state) => {
  return {
    todos: state.todos.filter(() => state.visible),
  };
};

// mapDispatchToProps() 方法接收 dispatch() 方法并返回期望注入到展示组件的 props 中的回调方法
const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id));
    },
  };
};

// 使用 connect() 创建 VisibleTodoList,并传入这两个函数
const VisibleTodoList = connect(mapStateToProps, mapDispatchToProps)(TodoList);

export default VisibleTodoList;

containers/AddTodo

import React, { createRef } from "react";
import { connect } from "react-redux";
import { addTodo } from "../actions/index";

// 添加项组件容器

function AddTodo({ dispatch }) {
  const inp = createRef();

  const submit = () => {
    const text = inp.current.value;
    dispatch(addTodo(text));
  };

  return (
    <div>
      <input ref={inp} />
      <button onClick={submit}>添加</button>
    </div>
  );
}

export default connect()(AddTodo);

containers/ButtonFooter.js

import { connect } from "react-redux";
import Footer from "../components/Footer";
import { setVisibilityFilter } from "../actions";

// 控制显示隐藏的按钮容器

const mapStateToProps = (state) => {
  return {};
};

const mapDispatchToProps = (dispatch) => {
  return {
    hanldeClick: (show) => {
      dispatch(setVisibilityFilter(show));
    },
  };
};

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

Reducers

reducers/todos.js

const initState = [
  {
    id: 0,
    text: '第一项',
    completed: false,
  },
];

const todos = (state = initState, action) => {
  switch (action.type) {
    case "ADD_TODO":
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false,
        },
      ];
    case "TOGGLE_TODO":
      return state.map((item) => {
        return item.id === action.id
          ? { ...item, completed: !item.completed }
          : item;
      });
    default:
      return state;
  }
};

export default todos;

reducers/visibilityFilter.js

const visibilityFilter = (state = true, action) => {
  switch (action.type) {
    case "SET_VISIBILITY_FILTER":
      return action.visible;
    default:
      return state;
  }
};

export default visibilityFilter;

reducers/index.js

import { combineReducers } from "redux";
import todos from "./todos";
import visibilityFilter from "./visibilityFilter";

// combineReducers 的作用:
// 把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数
// 然后就可以对这个 reducer 调用 createStore 方法

const todoApp = combineReducers({
  todos,
  visible: visibilityFilter,
});

export default todoApp;

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值