react中redux的介绍与使用

Posted 老张在线敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react中redux的介绍与使用相关的知识,希望对你有一定的参考价值。

1 redux是什么

1、redux是一个专门用于做状态管理的js库(不是react插件库)。
2、它可以用在react,angular,vue等项目中,但基本与react配合使用。
3、作用:集中式管理react应用中多个组件共享的状态。
4、 redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写

2 什么情况下需要使用redux

1、某个组件的状态,需要让其他组件可以随时拿到(共享)。
2、一个组件需要改变另一个组件的状态(通信)。
3、总体原则:能不用就不用,如果不用比较吃力才考虑使用。

3redux的方法

subscribe监测redux中状态的改变,如redux的状态发生了改变,就执行一次

语法:store.subscribe( ()=>{} )

dispatch:传递action

语法:{type:'',data:''}

getState:获取store的值

4 redux的api

createStore :专门用于创建redux中最为核心的store对象
applyMiddleware :中间件,用于配合redux-thunk(插件,需要引入)支持异步
combineReducers :当有多个状态时需要使用,可以将状态合并为一个对象

4.1 react-redux的api

Provider :无需自己给容器组件传递store,给根组件包裹一个即可

语法:<Provider store={store}>

connect : 生成一个容器组件,并暴露(类组件使用)

语法①: connect(mapStateToProps,mapDispatchToProps)(UI组件)
  		直接从函数的参数中就可以获取到dispatch
  		mapStateToProps(state)
  	    mapStateToProps(dispatch,ownProps) 

useSelector:相当于类组件的mapStateToProps

语法 :const state = useSelector(state=>state)

useDispatch: 相当于类组件的mapDispatchToProps

语法:
cosnt dispatch = useDispatch()
dispatch( action动作对象 )

【注意】:useDispatch()(action对象) 直接使用会报错

5、redux&react-redux 项目结构

store
	index.js 创建一个store容器
views
	Lists——>这个名是看文件,语义化就好了
		 redux 
			- Actions.js   返回一个或多个动作对象,一般为`{type:'',data:''}`
			- ActionsTypes.js   返回一个或多个常量,用做Actions和Reducer的type值
			- Reducer.js    返回一个纯函数,用于处理动作对象
		 index.js    将actions和reducer函数集中导出(方便管理)
		 index.jsx    容器组件和UI组件的结合体

6、一个简单的todolist案列

src/store/index.js
此文件主要就是创建一个仓库
将需要用到的reducer文件引入

import { createStore, combineReducers } from 'redux';

import { reducer as lists } from '../views/todo/_index'

const reducer = combineReducers({
  lists
})
// function newJson(obj) {
//   var json = (new Function('return' + obj))();
//   return json
// }
function newJson(obj){
  return JSON.parse(obj);
}
export default createStore(reducer, newJson(localStorage.getItem(('lists'))) || {});

src/router.js
此文件主要就是做一个根组件
通过provider向下传递store

import React from 'react';
import App from './App';
import { Provider } from 'react-redux';
import Store from './store/store'
import { BrowserRouter } from "react-router-dom";
const unsubscribe = Store.subscribe(() => {
  console.log(Store.getState)
  localStorage.setItem('lists', JSON.stringify(Store.getState()))
})
const Router = () => {

  return (
    <div>
      <BrowserRouter>
      <Provider store={Store}>
        <App />
      </Provider>
      </BrowserRouter>
     

    </div>
  )
}
export default Router

src/List/redux/actions.js
此文件主要是返回一个action动作对象
action动作对象必须要有一个type属性

import * as actiontypes from './actionTypes';
export const addList = (data) => ({ type: actiontypes.ADDList, data })
export const delList = (data) => ({ type: actiontypes.DELLIST, data })

src/List/redux/actionTypes.js
此文件主要是返回一个常量,目的是防止出现字母错误(默认是大写)

export const ADDList = "ADDLIST";
export const DELLIST = "DELLIST";

src/List/redux/reducer.js
此文件返回一个纯函数,用于接收dispatch传来的action,进行处理之后返回store
默认注入两个参数(preState,action)
preState需要设置初始值
reducer被第一次调用时,是store自动触发的,传递的preState是undefined
必须要有默认返回值

import * as actionTypes from './actionTypes';
const reducer = (preState = [], action) => {
  const { type, data } = action;

  switch (type) {
    case actionTypes.ADDList:
      const result = [
        data,
        ...preState
      ]
      console.log(result)
      return result
    case actionTypes.DELLIST:
      preState.splice(data, 1)
      return [...preState]
    default:
      return preState
  }
}
export default reducer

src/List/_index.js
汇总action和reducer方便管理
actions文件只有一个
reducer文件或许会有多个

import * as actions from './redux/actions';
import reducer from './redux/reducer';

export { actions, reducer }

src/List/_index.js (类组件写法)
类组件中获取cannect中函数映射的值和函数都是通过props拿到的

import React,{Component} from 'react';
import { connect } from 'react-redux';
import * as actions from './redux/actions';

class View extends Component{
  

  // 渲染函数
  rLsits = () => {
    let { lists } = this.props;
    return lists.map((value, index) => (
      <li key={index}>{value} <button onClick={()=>{this.delfn(index)}}>删除</button></li>
    ))
  }
    // 添加数据
  send = () => {
    let val = this.inp.value;
    this.props.addLists(val)
    this.inp.value=""
  }
   // 删除数据
   delfn = (index) => {
     this.props.delLists(index)
  }
  render() {
    return (
      <div>
        <h2>这是一个class类组件操作数组数据的例子</h2>
        <input ref={value=>this.inp=value} type="text" />
        <button onClick={()=>{this.send()}}>发送</button>
        {this.rLsits()}
      </div>
    )
  }
}
// 写法一  mapDispatchToProps是一个对象
export default connect(
  state => ({ lists: state.lists }),
  {
    addLists: actions.addList,
    delLists: actions.delList
  }
)(View)
// 写法二   mapDispatchToProps是一个函数
// export default connect(
//   state => ({ lists: state.lists }),
//   (dispatch, ownProps) => ({
//     addLists: data => { dispatch(actions.addList(data)) },
//     delLists: data => { dispatch(actions.delList(data)) }
//   })
// )(View)


// 写法三   mapDispatchToProps为null
// 需要在UI组件内通过this.props.dispath传递action动作对象
// export default connect(
//   state => ({ lists: state.lists }),
//   null
// )(View)

src/List/_index.js (函数组件写法)
函数组件的值是通过useSelector拿到的
函数组件的dispatch是通过useDispatch 拿到的

import React,{useRef} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import * as actions from './redux/actions'
const View = () => {
  let inp = useRef();
  const state = useSelector(state=>state)
  const dispath = useDispatch()
  
  const rLsits = () => {
    console.log('我执行了')
    return state.lists.map((value, index) => (
      <li key={index}>{value} <button onClick={()=>{delLists(index)}}>删除</button></li>
    ))
  }
  // 添加数据
  const send = () => {
    let val = inp.current.value;
    dispath(actions.addList(val))
    inp.current.value=""
  }
  // 删除数据
  const delLists = (index) => {
     dispath(actions.delList(index))
  }
  return (
    <div>
      <h2>这是一个函数组件操作数组数据的例子</h2>
      <input ref={inp} type="text" />
      <button onClick={send}>发送</button>
      {rLsits()}
    </div>
  )
  
}

export default View;

原文链接:https://blog.csdn.net/m0_57479235/article/details/119299162

以上是关于react中redux的介绍与使用的主要内容,如果未能解决你的问题,请参考以下文章

将状态传递给 React/Redux 中的递归嵌套组件

P19:Redux进阶-React-Redux介绍和安装

“ES7 React/Redux/GraphQL/React-Native 片段”不适用于 javascript 文件。除了安装它,我还需要配置其他东西吗?

React全家桶React-Redux

采用reactjs 开发时,redux 和 react-route 是怎么配合使用的

Redux 入门教程:React-Redux 的用法