react-redux在函数式组件中的应用

安装react-redux, redux,redux-thunk这三个库

1.在src新建redux文件夹

2.在redux文件夹下新建actions和reducers文件夹

3.在actions文件下建立为某组件生成action对象的js文件

4.在reducers文件下建立某组件服务的reducer,同时可以建立index.js用于汇总所有的reducer

5.redux文件夹下新建store.js,引入汇总之后的reducer,汇总的工作在reducers文件下的index.js

6.redux文件夹下新建常量文件constant.js

7.最后在入口文件main.jsx下注册store

另外需要两个钩子:useSelector(), useDispatch()

文件结构如下:

具体代码:

1.src\containers\Count\index.jsx

import React from "react";
import {
  increment,
  decrement,
  incrementAsync,
} from "../../redux/actions/count";
import { useRef } from "react";
import { useSelector, useDispatch } from "react-redux";

export default function Count() {
  const count = useSelector((state) => state.count);
  const personCount = useSelector((state) => state.persons.length);
  const dispatch = useDispatch();
  const selectRef = useRef();
  const Aincrement = () => {
    const { value } = selectRef.current;

    dispatch(increment(value * 1));
  };
  const Adecrement = () => {
    const { value } = selectRef.current;

    dispatch(decrement(value * 1));
  };
  const AincrementIfOdd = () => {
    const { value } = selectRef.current;
    if (count % 2 !== 0) {
      dispatch(increment(value * 1));
    }
  };
  const AincrementAsync = () => {
    const { value } = selectRef.current;
    dispatch(incrementAsync(value * 1, 500));
  };

  return (
    <div>
      count组件
      <h2>我是Count组件,下方组件总人数为:{personCount}</h2>
      <h4>当前求和为:{count}</h4>
      <select ref={selectRef}>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      &nbsp;
      <button onClick={Aincrement}>+</button>&nbsp;
      <button onClick={Adecrement}>-</button>&nbsp;
      <button onClick={AincrementIfOdd}>当前求和为奇数再加</button>&nbsp;
      <button onClick={AincrementAsync}>异步加</button>&nbsp;
    </div>
  );
}

2.src\containers\Person\index.jsx

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { useRef } from "react";
import { addPerson } from "../../redux/actions/person";

export default function Person() {
  const count = useSelector((state) => state.count);
  const persons = useSelector((state) => state.persons);
  const dispatch = useDispatch();
  const nameNode = useRef();
  const ageNode = useRef();
  const AaddPerson = () => {
    // 1. 获取输入框的值
    const name = nameNode.current.value;
    const age = ageNode.current.value;
    const personObj = { id: nanoid(), name, age };
    // 2. 调用接口
    dispatch(addPerson(personObj));
    // 3. 清空输入框
    nameNode.current.value = "";
    ageNode.current.value = "";
  };

  return (
    <div>
      <h2>我是Person组件,上方组件求和为{count}</h2>
      <input ref={nameNode} type="text" placeholder="输入名字" />
      <input ref={ageNode} type="text" placeholder="输入年龄" />
      <button onClick={AaddPerson}>添加</button>
      <ul>
        {persons.map((p) => {
          return (
            <li key={p.id}>
              {p.name}--{p.age}
            </li>
          );
        })}
      </ul>
    </div>
  );
}

3.src\redux\actions\count.js

/* 
	该文件专门为Count组件生成action对象
*/
import {INCREMENT,DECREMENT} from '../constant'

//同步action,就是指action的值为Object类型的一般对象
export const increment = data => ({type:INCREMENT,data})
export const decrement = data => ({type:DECREMENT,data})

//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。
export const incrementAsync = (data,time) => {
	return (dispatch)=>{
		setTimeout(()=>{
			dispatch(increment(data))
		},time)
	}
}

4.src\redux\actions\person.js

import {ADD_PERSON} from '../constant'

//创建增加一个人的action动作对象
export const addPerson = personObj => ({type:ADD_PERSON,data:personObj})

5.src\redux\reducers\count.js

/* 
	1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数
	2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
*/
import {INCREMENT,DECREMENT} from '../constant'

const initState = 0 //初始化状态
export default function countReducer(preState=initState,action){
	// console.log('countReducer@#@#@#');
	//从action对象中获取:type、data
	const {type,data} = action
	//根据type决定如何加工数据
	switch (type) {
		case INCREMENT: //如果是加
			return preState + data
		case DECREMENT: //若果是减
			return preState - data
		default:
			return preState
	}
}

 6.src\redux\reducers\person.js

import {ADD_PERSON} from '../constant'

//初始化人的列表
const initState = [{id:'001',name:'tom',age:18}]

export default function personReducer(preState=initState,action){
	// console.log('personReducer@#@#@#');
	const {type,data} = action
	switch (type) {
		case ADD_PERSON: //若是添加一个人
			//preState.unshift(data) //此处不可以这样写,这样会导致preState被改写了,personReducer就不是纯函数了。
			return [data,...preState]
		default:
			return preState
	}
}

 7.src\redux\reducers\index.js

/* 
	该文件用于汇总所有的reducer为一个总的reducer
*/
//引入combineReducers,用于汇总多个reducer
import {combineReducers} from 'redux'
//引入为Count组件服务的reducer
import count from './count'
//引入为Person组件服务的reducer
import persons from './person'

//汇总所有的reducer变为一个总的reducer
export default  combineReducers({
	count,
	persons
})

8. src\redux\constant.js

/* 
	该模块是用于定义action对象中type类型的常量值,目的只有一个:便于管理的同时防止程序员单词写错
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
export const ADD_PERSON = 'add_person'

9.src\redux\store.js

import {legacy_createStore, combineReducers,applyMiddleware} from "redux"
//引入汇总之后的reducer,汇总的工作在reducers文件下的index.js
import reducer from "./reducers";
//引入redux-thunk,用于支持异步action
import {thunk} from "redux-thunk";

//暴露store
export default legacy_createStore(
    reducer,
   applyMiddleware(thunk)
  );

 10.src\main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import { Provider } from "react-redux";
import store from "./redux/store";

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

11.src\App.jsx

import Person from "./containers/Person";
import Count from "./containers/Count";
function App() {
  return (
    <div>
      <Count></Count>
      <hr />
      <Person></Person>
    </div>
  );
}

export default App;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值