20行代码实现redux,50行代码实现react-redux

本文简要介绍了Redux的基本原理,包括其核心功能如维持应用状态、提供状态获取与更新方法,以及监听器注册与注销。同时,文章详细展示了Redux的createStore方法的简化实现,并提供了代码示例。此外,还探讨了React-Redux的实现思路,通过自定义connect函数,实现了与React-Redux类似的组件状态映射和操作。

redux的简陋版实现

简单实现了下redux,帮助理解redux的原理:

// 维持应用的 state
// 提供 getState() 方法获取 state
// 提供 dispatch(action) 方法更新 state
// 通过 subscribe(listener) 注册监听器
// 通过 subscribe(listener) 返回的函数注销监听器
// createStore参数为可变参数,第一个参数为reducer,第二个参数为初始state
export function createStore(...arg){
    let state = null;
    let reducer = arg[0];
    // 使用第二个参数为state初始化
    if(arg.length > 1){state = arg[1]}
    // 保存监听器的数据
    let listeners = [];
    let getState = () => state;
    let subscribe = listener => listeners.push(listener)
    let dispatch = (action) =>{
        //执行reducer函数,更新状态
        state = reducer(state,action)
        //遍历listeners,执行之中的监听器函数
        listeners.forEach(listener => listener())
    }
    return {
        getState,
        dispatch,
        subscribe
    }
}

实现了redux的createStore方法,代码没几行,应该能看懂吧。

如何使用?

// import {createStore} from 'redux'

import {createStore} from '../myredux'

import reducer from './reducer'

const initialState = {
    counter:0,
    title:'nihao'
}
const store = createStore(reducer,initialState)

export default store;

把导入redux的代码换成myredux即可,其他使用和redux一样。当然,redux的中间件并没有实现。

react-redux简陋版实现

react-redux实现思路

版本一:

let Container = ({store}) => {

    let [counter,setCounter] = useState(0);
    
    useEffect(() =>{
        store.subscribe(() => {
            setCounter(store.getState().counter)
        });
    })

    let add = () =>{
        store.dispatch({
            type:"INCREASE",
            num:1
        })
    }
    let min = () =>{
        store.dispatch({
            type:"DECREASE",
            num:1
        })
    }
    return  <Counter  counter={counter}  min={min}  add={add}/>
}


export default ({Consumer}) => (
    <Consumer>
        { (store) => <Container store={store}/>}
    
    </Consumer>)

使用

<Provider  store={store}>
    <Container  Consumer={Consumer}>
    </Container>
</Provider>

问题是, <Container/> 里面绑定了 <Counter/>

而且还需要把 <Consumer> 通过props传到 <Container/> 里。

并且 展示组件里也只能获取一个状态 counter

改进版

实现了 connect 函数,用法和 react-redux 基本一样,代码如下:

connect.js

import React,{createContext} from 'react';
const {Provider,Consumer} = createContext();
export const Container = ({store,children}) => {
    return (
        <div>
            <Provider value={store}>
                {children}
            </Provider>
        </div>
    )
}
class Inner extends React.Component{  
    constructor(props){
        super(props)
        this.state = {}
        let {mapStateToProps,store} = this.props;
        //从mapStateToProps获得用户需要的状态
        let mapState = mapStateToProps(store.getState());
        for(let key in mapState){
            this.state[key] = mapState[key]
        }
    }
    componentDidMount(){
        let {store} = this.props
        //注册监听,这样当state发生改变时,改变Inner的内部状态,把这个新状态在render中传给了展示组件Comp,Comp就可以实时获取最新状态了
        store.subscribe(()=>{
            let storeState = store.getState();
            for(let key  in this.state){
                this.setState({
                    [key]: storeState[key]
                })
            }
        })     
    }
    render() {
        let {store,Comp,mapDispatchToProps} = this.props;
        let actions = mapDispatchToProps(store.dispatch)
        //把状态和方法传入到展示组件中
        return (<Comp {...actions} {...this.state} />)
    }
}
//connnect是一个高阶组价,返回一个函数,接受展示组件为参数,使用<Consumer/>包装,传入 store
export const connect = (mapStateToProps,mapDispatchToProps) =>{
    return (Comp) => {
        return () => (
            <Consumer>
            { (store) =>( <Inner  Comp={Comp}  store={store} mapStateToProps={mapStateToProps} mapDispatchToProps={mapDispatchToProps}></Inner> ) }
        </Consumer>)
    }
}

如何使用:

使用方法,和 react-redux 基本上是一模一样的,只不过把 Provider 换成了 Container ,不过我完全可以叫 Provider ,一个名称而已。

在App.js:

import React from 'react';
import './App.css';
import store  from './store'
import Cart from './components/Cart1'
import {Container} from './connect.js'

function App() {
    return (
        <Container  store={store}>
            <Cart/>
        </Container>
    );
}

export default App;

cart.js

import React from 'react'
import {connect} from '../connect'

let Counter = ({counter,title,min,add,changeTitle}) =>{

    return (
        <div>
            <h1> {counter} </h1>
            <h2> { title }</h2>
            <button onClick={min}> - </button>
            <button onClick={add}> + </button>

            <button onClick={changeTitle}> update title </button>
        </div>)
}

const mapStateToProps = (state) => {
    return {
        counter: state.counter,
        title:state.title
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        add: () => {
            dispatch({type:"INCREASE",num:1})
        },
        min: () => {
            dispatch({type:"DECREASE",num:1})
        },
        changeTitle() {
            dispatch({type:"UPDATE_TITLE"})
        }
    }
}

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

已经可以和 react-redux 完全一样的用法。

当然,这里的实现只是为了帮助理解 react-redux 内部是如何实现,并不一定是最好用的,实际工作中直接使用 react-redux 就好了。

源码

代码放在Github上了,欢迎star: https://github.com/cooleye/co...

【故障诊断】【pytorch】基于CNN-LSTM故障分类的轴承故障诊断研究[西储大学数据](Python代码实现)内容概要:本文介绍了基于CNN-LSTM神经网络模型的轴承故障分类方法,利用PyTorch框架实现,采用西储大学(Case Western Reserve University)公开的轴承故障数据集进实验验证。该方法结合卷积神经网络(CNN)强大的特征提取能力和长短期记忆网络(LSTM)对时序数据的建模优势,实现对轴承不同故障类型和严重程度的高精度分类。文中详细阐述了数据预处理、模型构建、训练流程及结果分析过程,并提供了完整的Python代码实现,属于典型的工业设备故障诊断领域深度学习应用研究。; 适合人群:具备Python编程基础和深度学习基础知识的高校学生、科研人员及工业界从事设备状态监测与故障诊断的工程师,尤其适合正在开展相关课题研究或希望复现EI级别论文成果的研究者。; 使用场景及目标:① 学习如何使用PyTorch搭建CNN-LSTM混合模型进时间序列分类;② 掌握轴承振动信号的预处理与特征学习方法;③ 复现并改进基于公开数据集的故障诊断模型,用于学术论文撰写或实际工业场景验证; 阅读建议:建议读者结合提供的代码理解模型实现细节,重点关注数据加载、滑动窗口处理、网络结构设计及训练策略部分,鼓励在原有基础上尝试不同的网络结构或优化算法以提升分类性能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值