Как уже упоминалось в другом ответе, componentWillReceiveProps
постепенно сокращается, поэтому я постараюсь устранить его там, где это возможно.Вы будете заботиться о своем коде на будущее и будете делать логику компонентов более декларативной и легко рассуждаемой.Как кто-то, кто был ответственен (и был разочарован) злоупотреблением методом жизненного цикла, как это, вот несколько вещей, которые мне помогли.
Помните, что при использовании redux-thunk
наряду с передачей dispatch
в качествеПервый аргумент, вы также можете передать getState
в качестве второго.Это позволяет вам получать доступ к значениям состояния в логике действий, а не вносить их в подпорки вашего компонента и добавлять беспорядок.Что-то вроде:
export const ExampleAction = update =>
(dispatch, getState) => {
const { exampleBool } = getState().ExampleReducer
if (exampleBool) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update
})
}
}
Использование async / await в логике действий может быть спасением, когда ваше действие зависит от извлеченных результатов из вызова 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
})
}
}
Для случаев, когда рендеринг вашего компонентаповедение зависит от определенных значений состояния после того, как ваше состояние было обновлено, я настоятельно рекомендую повторно выбрать .Очень простой пример будет выглядеть примерно так:
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
}
}
)
Я должен упомянуть, что другой вариант будет использовать компоненты высшего порядка , но это может быть сложноИспользуйте этот подход, прежде чем иметь представление о том, как сохранить слишком много императивной логики в ваших компонентах (я усвоил это нелегко).