<center>redux+react-redux</center>

本文分享了作者在React和Redux开发过程中的经验,详细介绍了如何利用React-Redux进行状态管理,包括安装配置、组件连接及state与action的映射。

本文主要记录下自己在react道路上的爬坑过程 以及对于刚学习redux的同学提供一些可供参考的例子。

要知道redux和react并没有半毛钱的关系,redux甚至可以和jq一起用。 react-redux才是react的用于便捷操作redux的第三方插件。所以呢,学习react-redux之前我们要比较熟悉的了解redux的思想。

首先安装react-redux:

npm install react-redux --S

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';

class App extends Component {
    render() {
        const { PayIncrease, PayDecrease } = this.props;
        return (
            <div className="App">
                <div className="App">
                    <h2>当月工资为{this.props.tiger}</h2>
                    <button onClick={PayIncrease}>升职加薪</button>
                    <button onClick={PayDecrease}>迟到罚款</button>
                </div>
            </div>
        );
    }
}

const tiger = 10000

//这是action
const increase = {
    type: '涨工资'
}
const decrease = {
    type: '扣工资'
}
//这是reducer
const reducer = (state = tiger, action) => {
    switch (action.type) {
        case '涨工资':
            return state += 100;
        case '扣工资':
            return state -= 100;
        default:
            return state;
    }
}

//创建store
const store = createStore(reducer);

//需要渲染什么数据
function mapStateToProps(state) {
    return {
        tiger: state
    }
}
//需要触发什么行为
function mapDispatchToProps(dispatch) {
    return {
        PayIncrease: () => dispatch({ type: '涨工资' }),
        PayDecrease: () => dispatch({ type: '扣工资' })
    }
}

//连接组件
App = connect(mapStateToProps, mapDispatchToProps)(App)

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
)



首先最明显的是demo中引入react-redux的Provider和connect,它们非常重要!这里先大概解释下它们的作用:
Provider:它是react-redux 提供的一个 React 组件,作用是把state传给它的所有子组件,也就是说 当你用Provider传入数据后 ,下面的所有子组件都可以共享数据,十分的方便。
Provider的使用方法是:把Provider组件包裹在最外层的组件,如代码所示,把整个APP组件给包裹住,然后在Provider里面把store传过去。注意:一定是在Provider中传store,不能在APP组件中传store。
connect:它是一个高阶组件 所谓高阶组件就是你给它传入一个组件,它会给你返回新的加工后的组件,注重用法倒简单,深究其原理就有点难度。这里不做connect的深究,主要是学会它的用法,毕竟想要深究必须先会使用它。首先它有四个参数([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]),后面两个参数可以不写,不写的话它是有默认值的。我们主要关注下前两个参数mapStateToProps和mapDispatchToProps。
connect的使用方法是:把指定的state和指定的action与React组件连接起来,后面括号里面写UI组件名

import './index.scss' import Taro, { useLoad,pxTransform } from '@tarojs/taro' import { View, Text, Image, Button } from '@tarojs/components' import {useTabBarStore} from '@/store' import { Cell,Avatar,Popup} from '@nutui/nutui-react-taro' import { ArrowRight, IconFont } from '@nutui/icons-react-taro' import { useEffect, useState,useRef } from 'react' import MyButton from '@/components/my-button' import { useUserInfo} from '@/services' import MyLoginContent from '@/components/my-login-content' import { useUserStore } from '@/store' function Index() { //获取用户store const currentuserStore=useUserStore(); const {data: userdeatils, loading: userInfoLoading, run: getUserdetails} = useUserInfo() const [isRequesting, setIsRequesting] = useState(false); const [showLoginPopup, setShowLoginPopup] = useState(false); // 登录弹窗状态 const [isLogin, setIsLogin] = useState(false); const getUserInit = async () => { // if (isRequesting) return; // 防止重复点击 // setIsRequesting(true); try { const userInfo = await Taro.getUserProfile({ desc: '登录测试!授权不获取用户信息' }); if (!userInfo) { setIsRequesting(false); return; } console.log("my", userInfo); //将加密的用户数据发送到后端解密 await getUserdetails({ encryptedData: userInfo.encryptedData, iv: userInfo.iv, }); } catch (error) { console.error("获取用户信息失败:", error); } finally { // setIsRequesting(false); } }; useEffect(() => { const userInfo = JSON.parse(Taro.getStorageSync('user-storage')); if (userInfo.state.phoneNumber !== '') { setIsLogin(true); } }, []); // 监听 user 数据变化 // useEffect(() => { // console.log("user 或 hasRequestedUser 变化:", { // user, // hasRequestedUser, // userExists: !!user, // requestCount: requestCountRef.current, // loading: userInfoLoading // }); // if (user && hasRequestedUser) { // console.log("用户数据已更新:", user); // } // }, [user, hasRequestedUser, userInfoLoading]); // 监听 user 数据变化 // useEffect(() => { // if (user && hasRequestedUser) { // console.log("用户数据已更新:", user); // // 这里可以执行依赖用户数据的操作 // } // }, [user, hasRequestedUser]); const handleLogin = () => { setShowLoginPopup(true) } const onCancel = () => { setShowLoginPopup(false) } const updateUserInfo = () => { Taro.navigateTo({ url: '/pages/user/update-info/index' }) } const setSelectedIndex = useTabBarStore.use.setSelectedIndex() useEffect(() => { setSelectedIndex(3) }, [setSelectedIndex]) const listData = [ { id: 1, title: '购买套餐', pageUrl: '/pages/user/plan/index', iconName: 'buy' }, { id: 2, title: '购买记录', pageUrl: '/pages/user/purchase-report/index', iconName: 'buy-history' }, { id: 3, title: '档案管理', pageUrl: '/pages/user/archive-manage/index', iconName: 'archive' }, { id: 4, title: '隐私政策', pageUrl: '/pages/user/policy/index/index', iconName: 'privacy' }, { id: 5, title: '联系我们', pageUrl: '/pages/user/contact-us/index', iconName: 'phone' } ] return ( <View className='my-index'> <View className='my-header'> <View className='my-header-left'> <Avatar src={isLogin ? (currentuserStore.user.avatarUrl || `${process.env.IMAGE_DOMAIN}/my/avatar.png`) : `${process.env.IMAGE_DOMAIN}/my/avatar.png`} size='55' /> </View> <View className='my-header-center'> <View> <Text className='my-header-center-name'>{isLogin ? (currentuserStore.user.nickName || 'beiYi') : '未登录'}</Text> </View> <View> <Text className='my-header-center-subtitle'>个人账户</Text> </View> </View> <View className='my-header-right'> { isLogin? ( <View className='my-header-right-button login'> <MyButton label='编辑' styleType='six' onClick={updateUserInfo}/> </View> ): ( <View className='my-header-right-button'> <MyButton label='登录/注册' styleType='six' onClick={handleLogin}/> </View> ) } </View> </View> <View className='my-content'> <View className='my-content-count'> <View className='my-content-count-title'> <Text>购买次数</Text> </View> <View className='my-content-count-value' style={{color: '#a6d641'}}> <View className='my-content-count-number'> <Text>{isLogin ? currentuserStore.total : 0}</Text> </View> <View className='my-content-count-unit'> <Text >次</Text> </View> </View> </View> <View className='my-content-count'> <View className='my-content-count-title'> <Text >已使用</Text> </View> <View className='my-content-count-value' style={{color: '#fec302'}}> <View className='my-content-count-number'> <Text>{isLogin ? currentuserStore.used : 0}</Text> </View> <View className='my-content-count-unit'> <Text >次</Text> </View> </View> </View> <View className='my-content-count'> <View className='my-content-count-title'> <Text >待使用</Text> </View> <View className='my-content-count-value' style={{color: '#07bbae'}}> <View className='my-content-count-number'> <Text>{isLogin ? currentuserStore.count : 0}</Text> </View> <View className='my-content-count-unit'> <Text>次</Text> </View> </View> </View> </View> <View className='my-list'> <Cell.Group divider={false}> {listData.map(item => ( <Cell className="nutui-cell-clickable" key={item.id} title={ <View className='my-list-cell-title'> <View className='my-list-cell-title-icon'> <IconFont name={`${process.env.IMAGE_DOMAIN}/my/${item.iconName}.png`} // name={require(`@/assets/images/my/${item.iconName}.png`)} size={16} /> </View> <View className='my-list-cell-title-text'> {item.title} </View> </View> } align="center" extra={<ArrowRight size={16} color='#233A58'/>} onClick={() => { // 跳转页面 Taro.navigateTo({ url: item.pageUrl }) }} /> ))} </Cell.Group> </View> <Popup visible={showLoginPopup} position="bottom" round zIndex={10000} closeOnOverlayClick={false} onClose={() => { setShowLoginPopup(false) }} > <View className="popup-content"> <MyLoginContent onCancel={onCancel} setIsLogin={setIsLogin} /> </View> </Popup> {/* <View> <Button onClick={getUserInit}>获取用户信息</Button> </View> {userInfoLoading ? ( <Text>加载中...</Text> ) : user ? ( <View> <Text>{user.nickName}</Text> <Image src={user.avatarUrl || ''} /> </View> ) : ( <Text>请点击按钮获取用户信息</Text> )} */} </View> ) } export default Index 为什么只有登陆后,只有点击编辑返回后才能在主页显示store中的昵称和头像,我需要登陆后直接就显示
11-01
基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值