何时在 React 应用程序中使用 Dispatcher



我在ReactJS中使用Dispatcher时遇到了一些问题。因此,我尝试从商店中删除此调度程序,并且商店仍然运行良好。正确存储保存我的数据和更改事件效果很好。

现在,在我们的应用程序中使用调度程序有点令人困惑。

这是代码

MenuList是我的组件,我在其中调用MenuStore.getMenuFromAPI(),之后我还添加了MenuStoreonChange事件。

class MenuList extends React.Component{
constructor(){
super();
this.state = {open:false, menuList:"",numbering:-1}
}
componentWillMount(){
var that = this;
MenuStore.getMenuFromAPI();
MenuStore.on("change", ()=> {
that.setState({menuList:MenuStore.getMenu()});
})
}
componentWillReceiveProps(nextProps){
if(nextProps.show!=this.props.show){
this.setState({open:nextProps.show});
}
}
render(){
const { classes } = this.props;
return (
<div>My MEnu</div>
)
}
}

菜单商店

class MenuStore extends EventEmitter {
constructor() {
super();
this.menu = null;
}
getMenu(){
return this.menu;
}
getMenuFromAPI(){
var that = this;
$.ajax({
type: "POST",
url: LinkConstants.GETMENU,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: "",
dataType :"json",
success: function(response) {
that.menu =response;
that.emit("change");
}.bind(this),
error: function(xhr, status, err) {
console.log(err);
}.bind(this)
});
}
// handleAction(action) {
//   switch (action.type) {
//     case ActionTypes.MENU: {
//       this.getMenuFromAPI();
//       break;
//     }
//   }
// }
}
const menuStore = new MenuStore;
//Dispatcher.register(menuStore.handleAction.bind(menuStore));
export default menuStore;

如您所见,我注释掉了Dispatcher.register行和handleAction函数。

上面的代码工作正常,但我想知道为什么在这里使用调度程序?

如果我想只将我的数据存储在 MenuStore 中,并从应用程序中任何组件的 MenuStore 中取回它。因此,有必要使用调度程序和操作,或者仅与商店合作。

请通过适当的示例或案例场景(如果可能)澄清我的疑问,何时使用调度程序和操作或何时仅与商店合作。

在你的例子中,你根本没有使用Redux,你刚刚创建了一个类,用作获取数据的简单存储,但你没有使用任何Redux功能。

Redux 是关于一个存储的,它只是一个表示应用程序状态树的普通对象。为了更改此状态,您需要调度操作。动作只是描述所发生情况的简单对象。每个操作都有一个描述操作的type字段。操作由化简器处理,化简器是获取当前状态和调度操作并决定应用程序的下一个状态的函数。这是几句话的 Redux。

Redux 存储有一个名为dispatch的方法,用于调度操作。如 Redux 文档中所述,这是触发状态更改的唯一方法。

假设我们有一个待办事项列表应用程序。我们的商店可能表示为字符串数组(待办事项)。

要将新项目添加到列表中,我们将定义一个简单的操作:

const addItemAction = (item = '') => ({
type: 'ADD_ITEM',
data: item,
});

调度此操作可以从组件的一个方法中完成,这些方法将附加到某个键盘/鼠标事件:

class TodoList extends React.Component {
...
// addNewItem is called with a value from a text field
addNewItem(item) {
store.dispatch(addItemAction(item));
}
...
}

正如我上面提到的,状态是由化简器函数改变的。化简器决定是否更改状态以及如何更改状态。如果调度操作不应更改状态,则只需返回接收状态:

function todoReducer(state = [], action) {
switch(action.type) {
case 'ADD_ITEM':
return [...state, action.data];
break;
default:
return state;
}
}

Reducer 传递给 createStore 方法:

import { createStore } from 'redux'    
const store = createStore(todoReducer);

在 TodoList 组件中,您可以使用 store.subscribe 方法订阅商店,该方法接受每次存储状态更改时都会调用的回调函数。检测到更改时,可以调用组件的 setState 来设置组件状态的列表,并导致组件重新呈现:

class TodoList extends React.Component {
....
componentDidMount() {
this.storeSubscription = store.subscribe((state) => {
// For the example I'm just setting the state (list of todos) 
// without checking if it changed or not
this.setState({
todos: state,
});
});
}
render() {
return this.state.todos.map(todo => <div>{todo}</div>);
}
....
}

这是使用 Redux 的一个几乎完整的示例。我们使用操作来描述应用程序中的事件,我们使用商店的dispatch方法将操作调度到存储,Redux 将在获得新操作时调用化简器,化简器计算新状态,我们的组件使用存储的subscribe方法检测更改。

在更复杂的应用程序中,还有更多事情需要考虑和照顾。你可能会有一个更复杂的状态树,所以你需要额外的化简器来计算状态。此外,在某些步骤中,您需要考虑与一些帮助程序合作,以减少订阅状态更改和检测更改的开销。

在更复杂的应用程序中,您可能会通过绑定库(如react-redux)将组件连接到存储区,以便组件通过 props 接收存储区的相关部分,这将节省订阅存储更改和决定何时重新渲染组件的开销。

我建议观看Dan Abramov的"Getting started with Redux",以更多地了解什么是Redux以及如何使用它。 Redux 入门

最新更新