引出:
由于使用react传数据比较麻烦,所以可以使用redux去维护一个相当于全局变量的state,可以方便传数据。
一:redux相关基本思想流程
步骤:
1.创建redux-app,使用命令:create-react-app redux-app
2.进入 cd redux-app 安装redux库使用命令:npm i redux react-redux @reduxjs/toolkit
3.使用 nmp start 启动
4.先定义一个简单的redux,只维护一个数据,代码如下:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
//引入API
const f1 = (state = 0, action) => {
switch(action.type){
case 'add':
return state + 1;
case "sub":
return state - 1;
default:
return state;
}
}
//创建一个结点的数,用store去维护
const store = configureStore({
reducer: f1
});
console.log(store.getState())//输出state树中的值:0
5.修改state值,需要使用dispatch,它传入一个参数action,对整棵state树操作一遍。如下:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
//引入API
const f1 = (state = 0, action) => {
switch(action.type){
case 'add':
return state + 1;
case "sub":
return state - 1;
default:
return state;
}
}
//创建一个结点的数,用store去维护
const store = configureStore({
reducer: f1
});
store.dispatch({type: "add"})
console.log(store.getState())//输出state树中的值:1
6.可以通过API:subscribe查看他的执行
subscribe是每次dispatch后执行:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
//引入API
const f1 = (state = 0, action) => {
switch(action.type){
case 'add':
return state + 1;
case "sub":
return state - 1;
default:
return state;
}
}
//创建一个结点的数,用store去维护
const store = configureStore({
reducer: f1
});
store.subscribe(() => {console.log(store.getState())});
store.dispatch({type: "add"})
store.dispatch({type: "add"})
store.dispatch({type: "sub"})
store.dispatch({type: "add"})
store.dispatch({type: "add"})
输出值为:1 2 1 2 3
7.现在我们去维护两个结点的树,代码如下:
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
//引入API
const f1 = (state = 0, action) => {
switch(action.type){
case 'add':
return state + action.value;
case "sub":
return state - action.value;
default:
return state;
}
}
const f2 = (state = "", action) => {
switch(action.type){
case "concat":
return state + action.character;
default:
return state;
}
}
//f3作用,构建f1 和 f2 这一颗树,连接作用
const f3 = (state = {}, action) => {
return {
f1: f1(state.f1, action),
f2: f2(state.f2, action),
}
}
//创建一个结点的数,用store去维护
const store = configureStore({
reducer: f3
});
store.subscribe(() => {console.log(store.getState())});
store.dispatch({type: "add",value: 1})
store.dispatch({type: "add",value: 1})
store.dispatch({type: "add",value: 1})
store.dispatch({type: "add",value: 1})
store.dispatch({type: "sub",value: 1})
store.dispatch({type: "concat",character: "只因你太美"})
输出:
?另外,上面的f3也可以使用API简洁一下,作用完全相同
引入API:import { combineReducers } from 'redux';
//f3作用,构建f1 和 f2 这一颗树,连接作用
const f3 = combineReducers({
f1: f1,
f2: f2,
})
?上述就是redux本身的一个思想,一般是不常使用的,除非项目比较大。
二:接下来实现redux与react结合起来:
步骤:
1.结合react提供了Provider:import { combineReducers } from 'redux';
如果想在项目中使用redux的话,需要用Provider将项目包裹起来。
2.接下里通过三个组件来演示:App,number,和 string
注解:App包含number和string
通过number修改string的值
通过string修改number的值
3.在src下创建compoent文件夹
文件夹下创建三个组件,分别命名:app.jsx ,? ? ?number.jsx,? ? ??string.jsx
三个组件代码如下:
app.jsx
import React, { Component } from 'react';
import Number from './number';
import String from './string';
class App extends Component {
state = { }
render() {
return (
<React.Fragment>
<Number />
<hr />
<String />
</React.Fragment>
);
}
}
export default App;
number.jsx
import React, { Component } from 'react';
class Number extends Component {
state = { }
render() {
return (
<React.Fragment>
<h3>Number</h3>
</React.Fragment>
);
}
}
export default Number;
string.jsx
import React, { Component, Fragment } from 'react';
class String extends Component {
state = { }
render() {
return (
<React.Fragment>
<h3>String</h3>
</React.Fragment>
);
}
}
export default String;
需要注意的是:Provider 需要传入属性store
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
输出:
4.connect(mapStateToProps, mapDispatchToProps)函数:用来将store与组件关联起来。 mapStateToProps:每次store中的状态更新后调用一次,用来更新组件中的值。
代码如下:
number.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
class Number extends Component {
state = { }
render() {
return (
<React.Fragment>
<h3>Number</h3>
<div>{this.props.number}</div>
</React.Fragment>
);
}
}
const mapStateToProps = (state, props) => {
return {
number: state.number,
}
}
export default connect(mapStateToProps)(Number);
?string.jsx
import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';
class String extends Component {
state = { }
render() {
return (
<React.Fragment>
<h3>String</h3>
<div>{this.props.string}</div>
</React.Fragment>
);
}
}
const mapStateToProps = (state, props) =>{
return {
string :state.string,
}
}
export default connect(mapStateToProps)(String);
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
//引入API
import { combineReducers } from 'redux';
import App from './compoent/app';
import { Provider } from 'react-redux';
const f1 = (state = 0, action) => {
switch(action.type){
case 'add':
return state + action.value;
case "sub":
return state - action.value;
default:
return state;
}
}
const f2 = (state = "只因你太美", action) => {
switch(action.type){
case "concat":
return state + action.character;
default:
return state;
}
}
//f3作用,构建f1 和 f2 这一颗树,连接作用
const f3 = combineReducers({
number: f1,
string: f2,
})
//创建一个结点的数,用store去维护
const store = configureStore({
reducer: f3
});
store.subscribe(() => {console.log(store.getState())});
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
输出:
5.如何在Number修改String的值
代码如下:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class Number extends Component {
state = { }
handleClick = () => {
this.props.concat("你干嘛哎哟~~~");
}
render() {
return (
<React.Fragment>
<h3>Number</h3>
<div>{this.props.number}</div>
<button onClick={this.handleClick}>添加</button>
</React.Fragment>
);
}
}
const mapDispatchToProps = {
concat: (c) => {
return {
type: "concat",
character: c,
}
}
}
const mapStateToProps = (state, props) => {
return {
number: state.number,
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Number);
这样我们点击添加按钮,就会修改String的值如下点击四次按钮:
?6.同理可以实现在String中修改Number如下:
import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';
class String extends Component {
state = { }
handleClickAdd = () =>{
this.props.add(2)
}
handleClickSub = () => {
this.props.sub(2)
}
render() {
return (
<React.Fragment>
<h3>String</h3>
<div>{this.props.string}</div>
<button onClick={this.handleClickAdd}>加</button>
<button onClick={this.handleClickSub}>减</button>
</React.Fragment>
);
}
}
const mapStateToProps = (state, props) =>{
return {
string :state.string,
}
}
const mapDispatchToProps = {
add: (x) => {
return {
type:"add",
value: x,
}
},
sub: (x) => {
return {
type: "sub",
value: x,
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(String);
输出:
?
React-Redux基本概念: Provider组件:用来包裹整个项目,其store属性用来存储redux的store对象。 connect(mapStateToProps, mapDispatchToProps)函数:用来将store与组件关联起来。 mapStateToProps:每次store中的状态更新后调用一次,用来更新组件中的值。 mapDispatchToProps:组件创建时调用一次,用来将store的dispatch函数传入组件。
综上:redux其实就是一个树的遍历。
如有不足,烦请指点。
?
|