Redux配合React的简单应用

Redux配合React的简单应用

Redux配合React的简单应用 之前正在重构VocaloidInfo网易云插件,用到了Typescript+React,正好拿出来水一水 需求是这样的: 用户打开歌曲页面时,从VocaDB抓取数据,因为抓取需要一定的时间,所以在结果返回之前要显示一段文字 结果返回之后,要把这段文字更新成数据 用

Redux配合React的简单应用

之前正在重构VocaloidInfo网易云插件,用到了Typescript+React,正好拿出来水一水

需求是这样的:

  • 用户打开歌曲页面时,从VocaDB抓取数据,因为抓取需要一定的时间,所以在结果返回之前要显示一段文字

  • 结果返回之后,要把这段文字更新成数据

  • 用户切换歌曲之后也要刷新数据

    显示文字的部分就用React组件来完成,但是需要对里面的数据进行更新,所以使用redux做个简易的更新

Redux部分

Action

Action可以解释为 更改数据(state)的一种行为,拥有两个属性 typedata ,理论上来说我们应该通过Reducer对action的type进行判断,然后决定如何通过data更新state

比如一个int类型的state,有两种type addminus 。如果type为 add 就让state加上data,如果type为 minus 就让state减去data

Reducer

Reducer是一个函数,他接受state和action,返回新的state

在Reducer中我们需要对action的 type 进行判断,再通过action的 data 对state进行处理,然后返回新的state

Store

store就是Redux的数据储存器,他负责储存state,当调用他的 dispatch 方法时,他通过自己的reducer和dispatch方法参数中的action来更新state

实战

这里需要实现一个歌曲信息的Store,

由于我的需求比较特殊,歌曲的数据其实需要的时间很短,换一首歌之后原来的数据就不用了,而且action中的type和data我的react组件都要用到,所以我决定直接抛弃state,直接把action当成state里面给React组件用

代码具体如下:

import { configureStore, Action } from "@reduxjs/toolkit"; //导包

// 这边定义了SongAction的三种type
export enum SongActionType {
    LOADING, //歌曲数据正在加载中
    LOADED, //歌曲数据已经加载完毕
    FAILED, //没有找到歌曲数据
    ALL = LOADING | LOADED | FAILED
}

// 定义SongAction
export interface SongAction extends Action  {
    type: SongActionType,
    data: {
        vocadbData: any, //歌曲的vocadb数据
        bilibiliData?: any //歌曲的bilibili数据
    }
}

// 定义reducer
const reducer = ( _, action: SongAction) => { //第一个参数中的下划线其实应该是state, 只不过我不需要所以就把它扔了,直接把原始的action分发下去
    return action;
}

// 创建store
export const SongInfoStore = configureStore({ reducer: reducer });

Redux部分到此结束。

React部分

React部分需要对store进行订阅实现数据更新,这里直接贴代码:

// 歌曲数据的React组件
export default abstract class DefaultSongInfo extends React.Component<{store: Store<SongAction> }> {
    // 通过store的subscribe方法订阅数据,实现更新
    componentDidMount(): void {
      this.props.store.subscribe(() => {
        this.forceUpdate();
      });
    }
    
    render() {
      const store = this.props.store;
      const action = store.getState();
      
      // 接下来就是根据action对应的渲染数据,不多展开了
    }
}

想要渲染这个组件的话就用以下代码 (ReactDOM):

ReactDOM.render(<DefaultSongInfo { ...{store: SongInfoStore} }>, 挂载点);

更新数据

使用 dispatch 方法更新数据:

抓取数据前:

SongInfoStore.dispatch( {type: SongActionType.LOADING } );

成功抓取数据:

SongInfoStore.dispatch( { type: SongActionType.LOADED , data: data } )

如果失败了:

SongInfoStore.dispatch( {type: SongActionType.FAILED } );
LICENSED UNDER CC BY-NC-SA 4.0
Comment