一段时间以来,我一直在用redux使用react-native,当prop发生更改时,我学会调用动作的方式是使用componentWillReceiveProps,但是当我使用它时,我需要在if和它之间传递如果出错,那么我需要添加更多的东西来防止它。
这是我做过的一个例子。我知道这不是最好的方法,但这是我能想到的。
componentWillReceiveProps(newProps) {
if(Object.keys(newProps.selected_product).length > 0) {
if(Object.keys(this.props.current_location).length > 0 || Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
this.props.verifyProductById(newProps.selected_product, newProps.current_location, this.props.token);
} else {
this.props.statusScanner(false);
this._handleNextPage(1);
}
} else if(Object.keys(newProps.historic_product_confirm).length > 0) {
if(newProps.historic_product_confirm.location._id == newProps.current_location._id)
this.props.handleModalConfirmPrice(!this.props.modal_confirmPrice_status)
} else if(newProps.scanResult != "") {
this.props.statusScanner(false);
if(Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
} else {
this._handleNextPage(1);
}
} else {
this._handleNextPage(0);
}
}
当道具改变时,我需要一种健康的方式来称呼我的动作。
编辑: 这里有完整的OfferScene和操作文件示例:
OfferScene: https://gist.github.com/macanhajc/0ac98bbd2974d2f6fac96d9e30fd0642
UtilityActions: https://gist.github.com/macanhajc/f10960a8254b7659457f8a09c848c8cf
答案 0 :(得分:0)
在代码的清晰性方面,我同意@AnuragChutani和@Goldy;将其分解为更多的组件或功能。
现在,在对componentWillReceiveProps函数进行一些检查之后,它绝对不够具体,不足以精确地缩小哪些prop更改。如果任何已连接的redux变量发生更改,则每次都会调用componentWillReceiveProps函数。
例如如果更新了“令牌”或“ selected_product”,即使您不希望它触发令牌更新,也会触发componentWillReceiveProps。
您可以在道具中使用比较来更新特定变量。 例如使用lodash
if(!_.isEqual( nextProps.selected_product, this.props.selected_product ))
// if props are different/updated, do something
第二,您可以在操作中调用操作/回调以缩小导航范围。 例如
takePicture = (camera, options){
...
//on success
dispatch(handleModalConfirmPrice())
...
}}
答案 1 :(得分:0)
如另一个答案中所述,componentWillReceiveProps
正在被淘汰,所以我将力图尽可能地消除它。您将对代码进行过时的验证,并使组件逻辑更具声明性且易于推理。作为对这样的生命周期方法滥用负责(并为此感到沮丧)的人,以下是一些对我有所帮助的事情。
请记住,在使用redux-thunk
时,将dispatch
作为第一个参数传递,也可以将getState
作为第二个参数传递。这使您可以在操作逻辑中访问状态值,而不必将其带入组件的属性并增加混乱。像这样:
export const ExampleAction = update =>
(dispatch, getState) => {
const { exampleBool } = getState().ExampleReducer
if (exampleBool) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update
})
}
}
当您的操作依赖于API调用的提取结果时,在操作逻辑中使用异步/等待可以节省很多时间:
export const ExampleAction = () =>
async (dispatch, getState) => {
const { valueToCheck } = getState().ExampleReducer
, result = await someAPICall(valueToCheck)
.catch(e => console.log(e))
if (result.length > 0) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update: result
})
}
}
对于状态更新后组件的呈现行为取决于某些状态值的情况,我强烈建议reselect。一个非常基本的示例如下:
component.js
import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import { shouldDisplayItems } from '../selectors'
import MyListviewComponent from './myListview'
class ItemList extends Component {
render() {
const { shouldDisplayItems, items } = this.props
return (
<>
{shouldDisplayItems && <MyListviewComponent items={items} />}
</>
)
}
}
const mapStateToProps = ({ ListItems }) => shouldDisplayItems(ListItems)
export default connect(mapStateToProps)(ItemList)
selectors.js:
(假设您的ListItems简化程序具有参数items
和visibilityFilter
)
import { createSelector } from 'reselect'
export const shouldDisplayItems = createSelector(
[state => state],
({ items, visibilityFilter }) => {
return {
shouldDisplayItems: visibilityFilter && items.length > 0,
items
}
}
)
我应该提到另一种选择是使用higher-order components,但是在掌握如何将过多的命令式逻辑保留在组件之外之前,使用此方法可能会很棘手(我很难学方式)。