React-Reux快速上手
Redux是一个可预测化的React状态管理工具
Redux基本格式
-
先下载一个包:
npm i redux -
引入创建store的方法(相当于项目经理)
import { createStore } from 'redux' -
创建一个store,参数中需要传入一个reducer
const my_store = createStore(my_reducer) -
创建一个reducer,state必须要设置一个默认值(相当于程序员)
function my_reducer(state = inserState, action) { switch (action.type) { case 'ADD': return { ...state, count: state.count + action.count } // 最后必须要设置default default: return state } } -
创建一个action,相当于产品经理
const my_action = { type: 'ADD', count: 1 } -
使用store.diapatch方法,将action传入,这时才能执行reducer函数(这里相当于是产品经理向项目经理提出需求,程序员去执行)
my_store.dispatch(my_action)
让React和Rudux链接起来
文件的层级关系
-src
//用来管理Redux的文件夹
- redux
//reducer函数所在的js文件,在里面可以写所有的状态
-reducer.js
//文件中通过createStore()去将reducer和store链接起来,让reducer可以运作
-store.js
//根组件
-App.js
//需要渲染的组件
-Counter.js
//入口文件
-index.js
具体实现
index.js文件
//这里是React的正常操作
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App></App>, document.getElementById('root'))
App.js文件
import React, { Component } from 'react'
// 这里引入的Redux中的Provider组件,作用是将需要使用到Redux管理状态的应用包裹起来
import { Provider } from 'react-redux'
import my_store from './redux/store'
import Counter from './Counter'
{/* 根组件 */}
export default class App extends Component {
render() {
return (
// 包裹起来,和Router路由一样,整个应用只需要一个就行
// 这里要使用store属性,给这个应用绑定仓库
<Provider store={my_store}>
<div>
{/* 需要渲染的组件 */}
<Counter></Counter>
</div>
</Provider>
)
}
}
Counter.js文件
import React, { Component } from 'react'
// 导入connect高阶组件,connect实现了React和Redux的链接,可以上React组件使用Redux中的数据和方法
import { connect } from 'react-redux'
// 创建一个Counter组件,这是真实要渲染的组件
class Counter extends Component {
handle = () => {
// 这里要通过connect来让我们能够使用dispatch来修改数据
this.props.dispatch({ type: 'ADD', data: 1 })
}
render() {
return (
<div>
<button onClick={this.handle}><h1>点击{this.props.count}</h1></button>
</div>
)
}
}
// 用于将reducer中的数据映射到React组件的props上,让我们能够去使用dispatch方法,和获取到reduce中的状态
const my_state_to_props = state => {
return {
count: state.count
}
}
// 创建一个组件容器
const WithCounter = connect(my_state_to_props)(Counter)
// 将这个组件容器暴露出去渲染,但是实际渲染的是Counter组件
export default WithCounter
reducer.js文件
// 初始状态
let initState = {
// 在这里写各种状态
count: 1
}
// 创建一个reducer
export default function my_reducer(state = initState, action) {
switch (action.type) {
// 这里和action.type配对,修改数据
case 'ADD':
return {
// 使用解构可以让我们只修改某个数据,而不会将整个原始状态改变
...state,
count: state.count + action.data
}
//这里还是一样,需要书写一个默认的返回值,防止上面都没有配对到
default:
return state
}
}
store.js文件
import {createStore} from 'redux'
import my_reducer from './reducer'
// 创建一个store,并将reducer传入
const my_store = createStore(my_reducer)
export default my_store
步骤:
- 先创建React的基本结构(index.js App.js Counter.js)
- 创建dedux文件夹,在里面创建两个文件(reducer.js和store)
- reducer:不需要引入外部包,本身是一个执行函数,根据action.type属性来判断该如何执行,将函数暴露出去,函数有两个形参,state:表示当前最新的状态,第一次执行时(在创建阶段)需要设置一个默认状态。action:也就是告知reducer如何执行
- store:需要从redux包中引入一个createStore函数,函数中的参数为一个reducer,来创建一个store,并暴露出去
- 在App.js文件中,需要从react-redux包中拿到Provider组件,将App根组件包裹起来,并在Provider标签中写store属性,表示这个组件是使用了某个store仓库
- 需要redux中的数据的文件(比如Counter),需要通过一个connect高阶组件(从react-redux包引入)将Counter组件(展示组件)转换为WithCounter组件(容器组件),Counter.js文件中暴露出去的就不是Counter组件了而是容器组件WithCounter组件,在App中渲染的容器组件,但在页面中实际渲染的还是展示组件