react项目使用redux入门-1

redux

image

redux使用步骤

使用步骤:

  1. 定义一个 reducer 函数 (根据当前想要做的修改返回一个新的状态)
  2. 使用createStore方法传入 reducer函数 生成一个store实例对象
  3. 使用store实例的 subscribe方法 订阅数据的变化(数据一旦变化,可以得到通知)
  4. 使用store实例的 dispatch方法提交action对象 触发数据变化(告诉reducer你想怎么改数据)
  5. 使用store实例的 getState方法 获取最新的状态数据更新到视图中

实现计数器

image.png

需求:不和任何框架绑定,不使用任何构建工具,使用纯Redux实现计数器

代码实现:

<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>

<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>

<script>
  // 定义reducer函数 
  // 内部主要的工作是根据不同的action 返回不同的state
  function counterReducer (state = { count: 0 }, action) {
    switch (action.type) {
      case 'INCREMENT':
        return { count: state.count + 1 }
      case 'DECREMENT':
        return { count: state.count - 1 }
      default:
        return state
    }
  }
  // 使用reducer函数生成store实例
  const store = Redux.createStore(counterReducer)

  // 订阅数据变化
  store.subscribe(() => {
    console.log(store.getState())
    document.getElementById('count').innerText = store.getState().count

  })
  // 增
  const inBtn = document.getElementById('increment')
  inBtn.addEventListener('click', () => {
    store.dispatch({
      type: 'INCREMENT'
    })
  })
  // 减
  const dBtn = document.getElementById('decrement')
  dBtn.addEventListener('click', () => {
    store.dispatch({
      type: 'DECREMENT'
    })
  })
</script>

场景:切换语言

  1. 安装redux依赖包

    npm i redux --save
    
  2. 在根目录(src)下新建目录redux及文件

    mkdir src/redux
    touch src/redux/store.ts
    touch src/redux/languageReducer.ts
    
    • store.ts
    import { createStore } from 'redux'
    import languageReducer form './languageReducer.ts'
    
    const store = createStore(languageReducer)
    
    export default store
    
    • languageReducer.ts
    interface LanguageState {
      lng: 'zh' | 'en',
      languageList: {code: string, language: string}[]
    }
    
    export interface LanguageAction {
      type: 'language/change' | 'language/add',
      payload: any
    }
    
    const defaultStoreState: LanguageState = {
      lng: 'zh',
      languageList: [{ code: 'zh', language: '中文'}, { code: 'en', language: 'English'}]
    }
    
    export default (state = defaultStoreState, action: LanguageAction) => {
      switch(action.type){
          case: 'language/change':
          	return {...state, lng: action.payload}
          case: 'language/add':
          	return { ...state, languageList: [state.languageList, payload]}
        default:
          return state
      }
    }
    
  3. Header组件中使用store

    import { Component } from 'react'
    import { withRouter, RouteComponentProps } from 'react-router-dom'
    import { MenuInfo } from 'rc-menu/lib/interface'
    import { nanoid } from 'nanoid'
    import store from 'redux/store'
    import { LanguageState, LanguageAction } from 'redux/languageAction'
    
    const interface StateProps extends LangageState {}
    
    class HeaderComponent extends Component<RouteComponentProps, StateProps>{
      constructor(props:RouteComponentProps){
        super(props)
     		/* state初始化获取 store中的数据 */   
        const storeState = store.getState()
        this.state = {
          lng: storeState.lng,
          languageList: storeState.languageList
        }
      }
      
      componentDidMount(){
        /* subscribe */
        store.subscribe(() => {
          const storeState = store.getState()
          this.setState({
            lng: storeState.lng,
            languageList: storeState.languageList
          })
        })
      }
      
      render(){
        /* meun 的点击事件 */
        const oprateLanguage = ( e: MenuInfo ) => {
          let action
          if(e.key !== 'new'){
            action = {
              type: 'language/change',
              payload: e.key
            }
          }else{
            action = {
              type: 'language/add',
              payload: { code: `lng${nanoid()}`, language: '新语种'}
            }
          }
          /* dispatch */
          store.dispatch<LanguageAction>(action)
        }
        
        
        const menu = (
          <Menu>
            <Menu.Item key='new' onClick={oprateLanguage}>
              添加新语言
            </Menu.Item>
            {languageList.map(language => (
              <Menu.Item key={language.code} onClick={oprateLanguage}>
                {language.language}
              </Menu.Item>
            ))}
          </Menu>
        )
        
        return (
          <div>
            <Typography.Text className='mr40'>让旅游更幸福</Typography.Text>
            <Dropdown overlay={menu}>
            	<Button>
            		{languageList.find(language => language.code === lng)?.language}
              	<GlobalOutlined />
              </Button>
     				</Dropdown>
            <Button.Group>
                          <Button onClick={() => history.push('/signIn')}>登录</Button>
            <Button onClick={() => history.push('/register')}>注册</Button>
            </Button.Group>
    		</div>
        )
      }
    }
    
    export const Header = withRouter(HeaderComponent)
    
posted @ 2022-01-11 13:57  shine_lovely  阅读(43)  评论(0编辑  收藏  举报