B. Mohammad
B. Mohammad

Reputation: 2464

Stateful react-native functional component don't re-render when redux connected state change

I've started using hooks recently with react-native, so i have this connected component with a button that changes depending on a redux state. The button changes when redux state is updated inside the component, but not if it is from outside.

here is my button:

<TouchableOpacity
   style={styles.goPremiumContainer}
   onPress={() => pay()}>
   {props.premiumLoading ? (
     <ActivityIndicator size="small" color="#fff" />) 
     : 
    (<Text style={styles.goPremium}>
        {i18n.t('premium:go_premium')}
     </Text>)}
 </TouchableOpacity>

//
//
//

const mapStateToProps = state => {
  return {
    premiumLoading: state.premiumLoading,
  };
};

export default withNamespaces([], {wait: true})(
  connect(mapStateToProps)(Premium),
);

also the reducer:

const initialState = false;

function updateButtonLoading(state = initialState, action) {
  let nextState;
  switch (action.type) {
    case 'LOADING':
      nextState = true;
      return nextState || state;
    case 'NOT_LOADING':
      nextState = false;
      return nextState || state;

    default:
      return state;
  }
}

export default updateButtonLoading;

To update the button i call this action function:

async updatePremiumButton(actionType) {
  console.log('actionType',actionType)
  const action = {type: actionType};
  const unsubscribe = store.subscribe(() => true);
  await store.dispatch(action);
  await unsubscribe();
      },

THANKS!

Upvotes: 0

Views: 80

Answers (1)

Brian Thompson
Brian Thompson

Reputation: 14385

The issue is the logic inside your reducer.

switch (action.type) {
  case 'LOADING':
    nextState = true;
    return nextState || state;
  case 'NOT_LOADING':
    nextState = false;
    return nextState || state;
  default:
    return state;
}

It appears that what you really want to do is return the value you assign nextState, but the logic reads differently.

Currently the logic reads: If nextState is truthy use it, else return previous state.

In the NOT_LOADING case, you are intending to return the value false, but the logic reads: If false is true, return false, else return true. So you can see why this would never work.

Instead, simplify the cases and just return what you want the state to be. The || conditions don't seem to be necessary.

function updateButtonLoading(state = initialState, action) {
  switch (action.type) {
    case 'LOADING':
      return true;
    case 'NOT_LOADING':
      return false;
    default:
      return state;
  }
}

Upvotes: 2

Related Questions