javascript - 在 React 项目中添加 Redux
问题描述
在 React 项目中添加 redux(用 Redux 重构一个简单的项目)
考虑一个简单的项目,一个使用两个按钮的计数器应用程序,一个用于递增,另一个用于递减计数器值。
在实际场景中,我们使用状态来保存计数器值,如下所示:
在App.js中:
import React, {Component} from 'react';
import CounterApp from './CounterApp'
class App extends Component {
render() {
return (
<CounterApp/>
);
}
}
export default App;
在CounterApp.js中:
import React, {Component} from 'react';
class CounterApp extends Component {
state = {
counter: 0
};
handleIncrement = () => {
this.setState(prevState => ({
counter: prevState.counter + 1
}))
};
handleDecrement = () => {
this.setState(prevState => ({
counter: prevState.counter - 1
}))
};
render() {
return (
<div>
<button onClick={this.handleIncrement}>Increment</button>
<p>{this.state.counter}</p>
<button onClick={this.handleDecrement}>Decrement</button>
</div>
);
}
}
export default CounterApp;
一个简单而基本的示例,它使用 react 类组件实现并由两个函数处理程序 (handleIncrement
和handleDecrement
)处理
一个state
有值的,counter
我正在使用
prevState
,因为当您被迫使用时,这是最佳this.state.
实践setState
!
现在,这个Redux的实现会是什么?
解决方案
首先,您需要通过或将redux和react-redux包安装到您的项目中。npm
yarn
您可以使用一行代码简单地安装它们:
npm install redux react-redux --save
或用纱线:
yarn add redux react-redux
现在回到项目并使用以下名称创建 3 个文件:
action.js
,reducer.js
和 store.js
打开action.js
文件。我们应该为这个应用程序实现两个动作。一个用于递增,一个用于递减。
在action.js中
const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
const DECREMENT_COUNTER = 'DECREMENT_COUNTER';
const increment = () => ({type: INCREMENT_COUNTER});
const decrement = () => ({type: DECREMENT_COUNTER});
export {
INCREMENT_COUNTER,
DECREMENT_COUNTER,
increment,
decrement
}
动作是从组件分派到 redux 的简单函数,用于
store
通过 reducer 更改(状态)。
所以我们应该改变reducer.js:
import {INCREMENT_COUNTER, DECREMENT_COUNTER} from "./action";
const initialState = {
counter: 0
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case(INCREMENT_COUNTER):
return {
...state,
counter: state.counter + 1
};
case (DECREMENT_COUNTER):
return {
...state,
counter: state.counter - 1
};
default:
return state
}
};
export default reducer
使用 redux 有 3 个主要原则:
1-单一事实来源。整个应用程序的状态存储在单个存储中的对象树中。
2- 状态是只读的。改变状态的唯一方法是发出一个动作,一个描述发生了什么的对象。
3- 使用纯函数进行更改。
根据第二个原则,我们必须假设状态是不可变的,并且每个 case(in switch) 必须单独返回状态。在返回的状态中使用 ...state 意味着如果 initialState 将来会发生变化,这些情况将正常工作(在此示例中没有必要)。
我们在行动中的功能是纯粹的(第三条原则)
最后一个新文件store.js:
import {createStore} from "redux";
import reducer from './reducer'
const store = createStore(reducer);
export default store;
现在我们应该将此商店应用到我们的 App 组件。所以打开 App.js 文件并进行以下更改:
在App.js中:
import React, {Component} from 'react';
import CounterApp from './CounterApp'
import {Provider} from 'react-redux'
import store from './store'
class App extends Component {
render() {
return (
<Provider store={store}>
<CounterApp/>
</Provider>
);
}
}
export default App;
Provider 包装了CounterApp
组件并将传播store
到App
和CounterApp
所有其他子组件。
最后,更改CounterApp.js:
import React, {Component} from 'react';
import {connect} from "react-redux";
import {increment, decrement} from "./action";
class CounterApp extends Component {
handleIncrement = () => this.props.dispatch(increment());
handleDecrement = () => this.props.dispatch(decrement());
render() {
return (
<div>
<button onClick={this.handleIncrement}>Increment</button>
<p>{this.props.counter}</p>
<button onClick={this.handleDecrement}>Decrement</button>
</div>
);
}
}
const mapStateToProps = state => {
const counter = state.counter;
return {counter}
};
export default connect(mapStateToProps)(CounterApp);
我们正在使用increment
&decrement
动作将动作分派给 redux。
被移除了state
,我们创建了一个特殊的函数mapStateToProps' and use
connect 来代替 state 来将 state 连接到组件 props。
完成了!
推荐阅读
- vba - 将公式从一列复制到可变数量的列
- javascript - 如何将 Jqgrid 行数据作为数组获取
- javascript - 如何在 react-select v2 中创建 optgroup?
- javascript - 来自反应组件的 OnClick 相关功能不起作用
- c# - 每天午夜进行选择的 ASP.NET 例程
- domain-driven-design - 学习 DDD 和 CQRS
- c# - 如何在 SpecFlow 中更好地使用 ScenarioContext 以实现可维护性
- java - 如何从图像视图中裁剪图像的屏幕可见部分并将其存储?
- css - 滑块图像加载时间和显示问题
- android - v3.2 安卓资源编译失败