使用 redux-thunk / redux-observable with redux 的回调
Callbacks using redux-thunk / redux-observable with redux
我正在学习 redux 是如何工作的,但是它有很多代码来做简单的事情。例如,我想在显示之前从服务器加载一些数据。由于编辑原因,我不能简单地只使用传入的道具,而是必须将道具数据复制到本地状态。
据我所知,我必须发送 Fetch_request 操作。如果成功,fetch_success 操作将用新项目更新商店。然后更新的项目将导致我的组件的渲染功能更新。
在组件中
componentWillMount() {
this.props.FETCH_REQUEST(this.props.match.params.id);
}
...
在行动中
export function FETCH_REQUEST(id) {
api.get(...)
.then(d => FETCH_SUCCESS(d))
.catch(e => FETCH_FAILURE(e));
}
...
在减速器中
export function FETCH_REDUCER(state = {}, action ={}) {
switch (action.type) {
case 'FETCH_SUCCESS':
return { ...state, [action.payload.id]: ...action.payload }
...
}
返回组件
this.props.FETCH_REDUCER
// extra code for state, getting desired item from...
相反,我可以调用一个 react-thunk 函数并传递一些回调函数吗? react-thunk 可以更新存储,回调可以改变组件的本地状态。
在组件中
componentWillMount() {
this.props.FETCH_REQUEST(this.props.match.params.id, this.cbSuccess, this.cbFailure);
}
cbSuccess(data) {
// do something
}
cbFailure(error) {
// do something
}
...
在行动
export function FETCH_REQUEST(id, cbSuccess, cbFailure) {
api.get(...)
.then(d => {
cbSuccess(d);
FETCH_SUCCESS(d);
}).catch(e => {
cbFailure(d);
FETCH_FAILURE(e);
});
}
...
这样不妥吗?我可以用 redux-observable 做同样的事情吗?
更新 1
我将几乎所有东西都移到了 redux 存储区,甚至是编辑(即用 this.props.setState
替换了 this.setState
)。它简化了状态管理。但是,每次触发任何输入的 onChange 时,都会弹出一个新状态。 有人可以确认这是否可以吗? 由于 redux 为每个状态保存一个引用,我担心应用程序的内存管理。
首先,您应该在 componentDidMount
中调用您的 API 而不是 componentWillMount
。有关更多信息,请访问:
当您使用 redux store 时,您的组件使用 mapStateToProps
函数订阅状态更改,并且它们使用通过 mapDispatchToProps
函数添加道具的操作更改状态(假设您正在使用这些在你的连接调用中起作用)。
所以你已经在使用你的道具订阅状态变化。使用回调类似于让回调告诉您组件已经知道的更改,因为它的 props 发生了变化。道具的变化将触发组件的重新渲染以显示新状态。
更新:
您提到的输入字段在每个字符发生变化时触发 onChange 事件的情况,可能会导致对商店进行大量更新。正如我在评论中提到的,您可以使用像 _.debounce 这样的 api 来限制对商店的更新,以减少这种情况下状态更改的次数。有关如何处理此问题的更多信息,请访问 Perform debounce in React.js。
内存管理问题是使用 Redux 的实际应用程序中的一个实际问题。减少重复更新状态的影响的方法是
- 标准化状态的形状:http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
- 使用重新选择创建记忆选择器 (https://github.com/reactjs/reselect)
- 遵循有关 Redux github 页面性能的文章中提供的建议 (https://github.com/reactjs/redux/blob/master/docs/faq/Performance.md)
还要记住,虽然应该复制整个状态以防止变异,但只有发生变化的状态片需要更新。例如,如果你的状态持有 10 个对象,只有其中一个发生变化,你需要更新状态中新对象的引用,但其余 9 个未更改的对象仍然指向旧引用和你的对象总数内存是 11 而不是 20(不包括包含状态对象。)
我正在学习 redux 是如何工作的,但是它有很多代码来做简单的事情。例如,我想在显示之前从服务器加载一些数据。由于编辑原因,我不能简单地只使用传入的道具,而是必须将道具数据复制到本地状态。
据我所知,我必须发送 Fetch_request 操作。如果成功,fetch_success 操作将用新项目更新商店。然后更新的项目将导致我的组件的渲染功能更新。
在组件中
componentWillMount() {
this.props.FETCH_REQUEST(this.props.match.params.id);
}
...
在行动中
export function FETCH_REQUEST(id) {
api.get(...)
.then(d => FETCH_SUCCESS(d))
.catch(e => FETCH_FAILURE(e));
}
...
在减速器中
export function FETCH_REDUCER(state = {}, action ={}) {
switch (action.type) {
case 'FETCH_SUCCESS':
return { ...state, [action.payload.id]: ...action.payload }
...
}
返回组件
this.props.FETCH_REDUCER
// extra code for state, getting desired item from...
相反,我可以调用一个 react-thunk 函数并传递一些回调函数吗? react-thunk 可以更新存储,回调可以改变组件的本地状态。
在组件中
componentWillMount() {
this.props.FETCH_REQUEST(this.props.match.params.id, this.cbSuccess, this.cbFailure);
}
cbSuccess(data) {
// do something
}
cbFailure(error) {
// do something
}
...
在行动
export function FETCH_REQUEST(id, cbSuccess, cbFailure) {
api.get(...)
.then(d => {
cbSuccess(d);
FETCH_SUCCESS(d);
}).catch(e => {
cbFailure(d);
FETCH_FAILURE(e);
});
}
...
这样不妥吗?我可以用 redux-observable 做同样的事情吗?
更新 1
我将几乎所有东西都移到了 redux 存储区,甚至是编辑(即用 this.props.setState
替换了 this.setState
)。它简化了状态管理。但是,每次触发任何输入的 onChange 时,都会弹出一个新状态。 有人可以确认这是否可以吗? 由于 redux 为每个状态保存一个引用,我担心应用程序的内存管理。
首先,您应该在 componentDidMount
中调用您的 API 而不是 componentWillMount
。有关更多信息,请访问:
当您使用 redux store 时,您的组件使用 mapStateToProps
函数订阅状态更改,并且它们使用通过 mapDispatchToProps
函数添加道具的操作更改状态(假设您正在使用这些在你的连接调用中起作用)。
所以你已经在使用你的道具订阅状态变化。使用回调类似于让回调告诉您组件已经知道的更改,因为它的 props 发生了变化。道具的变化将触发组件的重新渲染以显示新状态。
更新: 您提到的输入字段在每个字符发生变化时触发 onChange 事件的情况,可能会导致对商店进行大量更新。正如我在评论中提到的,您可以使用像 _.debounce 这样的 api 来限制对商店的更新,以减少这种情况下状态更改的次数。有关如何处理此问题的更多信息,请访问 Perform debounce in React.js。
内存管理问题是使用 Redux 的实际应用程序中的一个实际问题。减少重复更新状态的影响的方法是
- 标准化状态的形状:http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
- 使用重新选择创建记忆选择器 (https://github.com/reactjs/reselect)
- 遵循有关 Redux github 页面性能的文章中提供的建议 (https://github.com/reactjs/redux/blob/master/docs/faq/Performance.md)
还要记住,虽然应该复制整个状态以防止变异,但只有发生变化的状态片需要更新。例如,如果你的状态持有 10 个对象,只有其中一个发生变化,你需要更新状态中新对象的引用,但其余 9 个未更改的对象仍然指向旧引用和你的对象总数内存是 11 而不是 20(不包括包含状态对象。)