问题
In React Native and Redux, I am using <NavigationCardStack/>
as the root component and render routes with _renderScene()
. But seems like whenever the root component re-renders with state update, it does not pass the state down every update, because I put console.log(this.props)
in the child component and logs the passed state, but it only logs once and that is the first time the app starts up and never logs after even if the root component re-renders with the state update.
Why isn't it passing down the updated state every time the state changes? And why doesn't the child component re-render whenever the root component does?
This is my set up:
_renderScene (props) {
const { route } = props.scene
return (
<route.component _handleNavigate={this._handleNavigate.bind(this)} state={this.props}/>
)
}
<NavigationCardStack
direction='horizontal'
navigationState={this.props.navigation}
onNavigate={this._handleNavigate.bind(this)}
renderScene={this._renderScene}
renderOverlay={this.renderOverlay}
style={styles.container}
/>
In _renderScene
, props
alone logs:
And this.props
logs the actually state passed down via Redux:
And in the child component childPage.js
, I am simply logging like so, and it logs the props passed down (_handleNavigate
and state
) correctly but the state
just continues to represent initial state even if it gets updated:
render() {
console.log(this.props.state)
return (
Thank you in advance!
EDIT
This is my reducer and the child component would just log the initialState here even though other properties have been added and updated:
const initialState = {
meetUp: false,
}
function itemReducer(state = initialState, action) {
switch(action.type) {
case ITEM_QUANTITY:
return {
...state,
quantity: action.quantity
}
case ITEM_PRICE:
return {
...state,
price: action.price
}
case ITEM_MEET_UP:
return {
...state,
meetUp: action.meetUp
}
default:
return state
}
}
export default itemReducer
And connected to the root component like so:
function mapStateToProps(state) {
return {
itemInfo: state.itemReducer,
...
}
}
export default connect(
mapStateToProps,
{
itemQuantity: (value) => itemQuantity(value),
itemPrice: (value) => itemPrice(value),
itemMeetUp: (value) => itemMeetUp(value),
}
)(NavigationRoot)
With following actions:
export function itemMeetUp(value) {
return {
type: ITEM_MEET_UP,
meetUp: value
}
}
export function itemQuantity(value) {
return {
type: ITEM_QUANTITY,
quantity: value
}
}
export function itemPrice(value) {
return {
type: ITEM_PRICE,
price: value
}
}
回答1:
There is only one reason that a child component does not render after a parent render - its shouldComponentUpdate method, or one from a component between it and the parent, has returned false. Often (particularly with Redux) shouldComponentUpdate methods are written to block the rerender if the properties haven't changed shallowly. Redux relies on you not mutating state, but instead always returning a new object with any changes from your reducer, otherwise the shouldComponentUpdate optimisation causes unexpected behaviour.
Could the problem be that you are modifying deep state rather than returning new objects? See http://redux.js.org/docs/basics/Reducers.html for more details.
回答2:
A first guess is that your NavigationCardStack isn't rerendering since it thinks the props being presented to it is unchanged. Try forcing a rerender (forceUpdate) and see what happens.
来源:https://stackoverflow.com/questions/39279531/react-native-redux-how-to-pass-down-updated-state-to-child-components-every-tim