什么都不说了,直接开用!
这两步是安装一个 react项目 并把在redux 使用过程中用到的插件安装下来
将状态及更新状态的行为合并在一起,方便实现状态维护
数据,驱动应用运行的数据
action 就是一个普通 JavaScript 对象,表示要更新 state 时的行为说明,通常有 type 和 payload 属性,type 表示 action 类型,payload 表示有效载荷
是一个纯函数,用于将 state 与 action 关联,在 reducer 中实现状态更新的操作,注意,在 reducer 中通常返回更新后的新的 state 对象,不要在原来的 state 上直接修改
要想更新 state 中的数据,你需要发起一个 action,dispatch 就是发起 action 的函数,会在 dispatch 函数内部调用到 reducer 函数(调用 reducer 函数时,传递 state 与 action 参数)
将原来的 src 目录清空
自己重新写入目录文件 下面这个文件目录结构说我要用到的文件和目录,展开的都是需要用到的
使用redux 的三个目录
actionsreducersstore先从reducer 开始 来使用 redux
reducer 是 纯函数,根据动作类型判断如何更新状态,会返回更新后的新状态值
vs code 有个插件 叫做 ES7 React/Redux/GraphQL/React-Native snippets 可以快速创建 reducer 函数
vs 里 输入 rxr 就会出现提示
这里我 用一个 登录用户的状态当作 demo
在 reducers 里 创建一个 user.js 文件写入以下代码
import { USER_LOGIN, USER_LOGOUT } from "../actions/user" // actions 里引入过来的动作类型 // 默认 state 值 const initialState = { username: '', isLogin: false } // 默认导出 动作类型 type 一般都是全部大写便于区分 参数 是 action里函数 调用 dispatch({type, payload }) 传递过来的 export default (state = initialState, { type, payload }) => { switch (type) { case USER_LOGIN: // 登录 将登录信息 返回给state return payload // 返回的是一个新的 state 替代上一个 case USER_LOGOUT: // 退出登录 恢复默认值 return { username: '', isLogin: false } default: return state } }在reducers 文件夹里创建一个index.js文件,用来做所有reducer 的合并
// 合并reducer redux提供的方法 import { combineReducers } from 'redux' import userReducer from './user' // combineReducers 里 传递的是一个对象, 每一个属性代表一个reducer export default combineReducers({ user: userReducer })上面代码引入了 actions 里的 代码, 那么我们去actions 里写入我们的 动作 和 携带的数据
用于生成在 reducer() 函数中第二个参数 action 对象的函数
这里会将动作类型 载荷 传递过来
在函数内部 调用 dispatch 这个函数发送 动作类型和载荷
在actions 里 创建 一个 user.js 文件
// 暴露 两个常量 表示 动作类型 export const USER_LOGIN = 'USER_LOGIN' export const USER_LOGOUT = 'USER_LOGOUT' // user 的 action 提交 数据到 reducer 等待处理 // login 登录所携带的参数 export const loginAction = ({ username, password }) => dispatch => { // 用 定时器 来模拟异步请求ajax这类的数据请求 setTimeout(() => { dispatch({ type: USER_LOGIN, payload: { isLogin: true, username, password } }) }, 1000) } // 退出登录 export const logoutAction = ( username ) => dispatch => { setTimeout(() => { dispatch({ type: USER_LOGIN, payload: { isLogin: true, username } }) }, 1000) }现在 reducer 和 action 都写好了,该去完成store 将 状态及更新状态的行为合并在一起
store里创建一个index.js 代码如下:
// 创建一个 store redux 提供的方法createStore // 如果有异步加载方法applyMiddleware 需要thunk做参数 import { createStore, applyMiddleware } from 'redux' import rootRedcer from '../reducers' // 引入 reducer import thunk from 'redux-thunk' export default createStore(rootRedcer, applyMiddleware(thunk))好了,现在 一个 关于 全局状态就已经 配置好了 , 现在该去使用它了
怎么使用它呢?
还记得之前安装的插件 react-redux 吗? 这个是将 store 里 存的 state 通过 全局上下文的方式共享出去
封装了 一个高阶组件使用,我们去引入就是
Provider 挂载 共享状态数据 (用在顶层组件,包裹需要使用数据的组件)
connect 连接,使用改变状态数据 (子组件)
在index.js 写入代码
import React from 'react' import { render } from 'react-dom' import { Provider } from 'react-redux' // 引入 组件 共享 store import store from './store' // 引入状态 import App from './App' // store={store} 当作属性挂载在组件 其他组件使用 this.props 调用 render( <Provider store={store} > <App /> </Provider>, document.getElementById('root') )数据已经共享出去了,现在我们去一个组件使用它
**在App.js 里使用 代码如下: **
import React, { Component } from 'react' import { connect } from 'react-redux' // 引入高阶组件 import { loginAction } from './actions/user' // 引入登录 的 action 函数 export class App extends Component { // 打印一下 this.props ,查看 是否传递到组件属性上 componentDidMount() { console.log(this.props) } // ES7语法 箭头函数 不然 不能使用 this login = () => { console.log('login') // 调用 传过来的函数 this.props.loginAction({ username: 'hello', password: '123456' }) } render() { return ( <div> app <button onClick={ this.login }>登录</button> <p>{ this.props.user.username ? this.props.user.username : '没有用户名' }</p> </div> ) } } // 这是 state 因为合并了 reducer 所以要用谁,就把它 点出来 const mapStateToProps = state => ({ user: state.user }) // 发起改变状态的函数 在action 里已经定义好了 , 直接导入 const mapDispatchToProps = { loginAction } // connect 使用 返回的返回值为 HOC 函数 再调用 传入需要的组件 ,返回一个组件 export default connect(mapStateToProps, mapDispatchToProps)(App)查看最终结果
点击登录按钮前
点击登录按钮后
以上就是redux 结合 react 的大致使用方法了,希望大家都能轻松驾驭,敲代码得心应手
