0
点赞
收藏
分享

微信扫一扫

react基础04--redux 管理数据


react基础04--redux 管理数据

  • ​​1 介绍​​
  • ​​2 方法&案例​​
  • ​​在多个组件中使用Store中的数据​​
  • ​​规范 store 写法​​
  • ​​修改Store中的数据​​
  • ​​refs属性获取元素对象​​
  • ​​redux-thunk 中间件​​
  • ​​3 注意事项​​
  • ​​4 说明​​

1 介绍

​​react基础03–render渲染、组件生命周期、组件通信​​ 中介绍了React render渲染、组件生命周期、组件通信等重要知识。本文在其基础上继续介绍 redux 数据管理的方法,并配以实际案例。

实际项目中,很多时候需要在多个组件或者多个页面显示统一个数据,例如商品数量,如果通过参数传递就显得很麻烦。此时我们就可以通过redux事项数据管理。

2 方法&案例

安装 redux 模块:
npm i redux --save
安装后在 package.json 中就可以看到 { “dependencies”: {“redux”: “^4.1.2”}}

在多个组件中使用Store中的数据

  1. 定义Store.js 文件,引用 createStore函数,返回 createStore 的回调
  2. 在哪里使用就在哪里调用,分别在 App.js 和 Demo.js 中通过 Store.getState().name 访问Store中的数据即可,不需要各种复杂的传参步骤

vim index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App 2-1</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

vim index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './Demo';

ReactDOM.render(
<Demo />
,document.getElementById('root')
);

vim Demo.js

import React, { Component } from 'react'
import App from './App';
import Store from './Store';

export default class Demo extends Component {
constructor(){
super();
this.state = {
msg: Store.getState().name
}
}
render() {
return (
<div>
<h1>this demo's Component, msg={this.state.msg}</h1>
<App />
</div>
)
}
}
export default

vim App.js

import React, { Component } from 'react'
import Store from './Store'

export class App extends Component {
constructor(){
super()

this.state = {
name: Store.getState().name
}
}
render() {
return (
<div>
this App is: {this.state.name}
</div>
)
}
}
export default

vim Store.js

import { createStore } from 'redux'

const defaultState = {
name: 'tom'
}
const store = createStore((state = defaultState,action)=>{
return state;
}
);
export default

结果:

react基础04--redux 管理数据_axios

规范 store 写法

当需要存储的数据较多的时候,如果将所有的数据都放在 Store.js, 那么将会很冗余,因此需要将其拆分出为一个单独的 reducer.js
vim App.js

import React, { Component } from 'react'
import Store from './Store'
import Header from './Header'
import Content from './Content'
import Footer from './Footer'

export class App extends Component {
constructor(){
super()
this.state = Store.getState()
}
render() {
return (
<div>
<h2> App.js: {this.state.name} </h2>
list: {this.state.list}
<Header />
<Content />
<Footer />
</div>
)
}
}
export default

vim reducer.js

const defaultState = {
name: 'tom',
list: [1,2,3,4,5]
}

export default ((state = defaultState,action)=>{
return state;
}
);

vim Store.js

import { createStore } from 'redux'
import reducer from './reducer';

const store = createStore(reducer);
export default

结果:

react基础04--redux 管理数据_redux管理数据_02

修改Store中的数据

当前端有操作的时候,可以捕获事件,在事件中将具体信息分发给reducer;
在reducer 中需要通过 action.type 来确认是哪个组件派发的,并将数据返回;
同时需要在组件中新增Store.subscribe函数,当其检测到更新就将数据更新到组件中;

vim reducer.js

const defaultState = {
name: 'tom',
list: [1,2,3,4,5]
}

export default (state = defaultState,action)=>{
if (action.type === 'change_name'){
let tmpState = state;
tmpState.name = action.name;
return tmpState
}
return state
};

vim Content.js

import React, { Component } from 'react'
import Store from './Store'

export class Content extends Component {
constructor(){
super()
this.state = Store.getState()

Store.subscribe(()=>{
console.log(Store.getState());
this.setState(Store.getState())
})
}
render() {
return (
<div>
内容 {this.state.name}
<p>
<input input={this.state.name} onChange={this.change.bind(this)}/>
<button>提交</button>
</p>
</div>
)
}
change(e){
let inputValue = e.target.value;
console.log(inputValue)
let action = {
type: 'change_name',
name: inputValue
}
Store.dispatch(action) // 把action 对象派发给reducer
}
}
export default

输出结果:

默认为 tom

react基础04--redux 管理数据_redux管理数据_03


输入bob后更新为bob

react基础04--redux 管理数据_react.js_04

注意:
如果只在change(e)事件中使用 this.setState, 那么只会更新 Content 组件。

this.setState({
name: inputValue
})

如果需要其它组件也更新相关字段,那么需要在其它组件中添加 Store.subscribe 函数。

refs属性获取元素对象

修改Store中的数据 中, 每次input中有变动就更新给各个组件,有时候需要输入完毕,点击提交的时候才将信息更新给不同的组件。
此时我们需要设置button 的onClick 事件,并且通过 input 的refs 获取元素的对象,并将该元素的值派发给reducer。

vim Content.js

import React, { Component } from 'react'
import Store from './Store'

export class Content extends Component {
constructor(){
super()
this.state = Store.getState()

Store.subscribe(()=>{
this.setState(Store.getState())
})
}
render() {
return (
<div>
内容 {this.state.name}
<p>
<input ref="inputValue"/>
<button onClick={this.click.bind(this)}>提交</button>
</p>
</div>
)
}
click(){
let inputValue = this.refs.inputValue.value;
console.log(inputValue)
let action = {
type: 'change_name',
name: inputValue
}
Store.dispatch(action) // 把action 对象派发给reducer
}
}
export default

redux-thunk 中间件

安装组件

npm i axios --save
npm

以上都是通过派发变量的方式改变参数,如果想派发函数,那么就需要redux-thunk中间件了。
需要在Store.js 中 createStore 引入 pplyMiddleware(thunk) 参数,在reducer.js 中引入对应的处理方法;
程序启动的时候将getList函数派发给thunk;
thunk 再将对应的数据派发给 reducer;
当 App 中的模块监听到 reducer的变动后,就会更新对应的数据。

vim data.json

{
"list": [5,6,7,8,9]
}

vim reducer.js

const defaultState = {
name: 'tom',
list: [1,2,3,4,5]
}

export default (state = defaultState,action)=>{
if (action.type === 'change_name'){
let tmpState = state;
tmpState.name = action.name;
return tmpState;
}
// 初始化list
if (action.type === 'init_list'){
console.log(action);
let tmpState = state;
tmpState.list = action.list;
return tmpState;
}
return state
};

vim Store.js

import { createStore, applyMiddleware } from 'redux'
import reducer from './reducer';
import thunk from 'redux-thunk'

const store = createStore(reducer, applyMiddleware(thunk));
export default

vim App.js

import React, { Component } from 'react'
import Store from './Store'
import Header from './Header'
import Content from './Content'
import Footer from './Footer'
import axios from 'axios'

export class App extends Component {
constructor(){
super()
this.state = Store.getState()
Store.subscribe(()=>{
this.setState(Store.getState())
})
}
componentDidMount(){
Store.dispatch(this.getList()) // 先派发给thunk
}
getList(){
return (dispatch)=>{
axios.get("http://localhost:3000/data.json")
.then((resp)=>{
// console.log(resp.data)
let action = {
type: 'init_list',
list: resp.data.list
}
dispatch(action) //派发给reducer
})
}
}
render() {
return (
<div>
<h2> App.js: {this.state.name} </h2>
list: {this.state.list}
<Header />
<Content />
<Footer />
</div>
)
}
}
export default

启动输出:

react基础04--redux 管理数据_react 修改store数据_05

3 注意事项

  1. 如果只是分发不同变量,直接用普通的reducer即可;如果需要分发函数,那么需要使用 redux-thunk 组件来实现。

4 说明

软件版本:
node 16.13.1
create-react-app 5.0.0
参考文档:
​​​React基础入门+综合案例​​​​react 官网​​​​React基础入门教程​​​​中国 NPM 镜像​​


举报

相关推荐

0 条评论