When an arrow is clicked the Cart Item View needs to expand that particular view and collapse any others currently expanded. The item id of that product is passed to the parent component to update which view is to be expanded (active). Although, the id is being passed and set on the expandedItem property in the reducer this does not get updated to the child component (even though it's being passed as prop on the child component). When the child component is re-evaluated at the end the expandedViewItem is still 0, which is it's default value. Does anyone know how to get the child component to receive the updated expandedItem value? Why is it still 0??
PLEASE watch the video I made debugging this issue: https://youtu.be/qEgxqAyWDpY
Here is where the value is evaluated in the child component:
render () {
const isExpanded = product.id === this.props.expandedViewId;
Here is the entire child component class:
export default class CartProductItem extends Component {
constructor(props) {
super(props);
this.state = {showCounter: false};
}
expandCartProductItem(id) {
this.props.onExpandClick(id);
this.setState(this.state);
}
updateDisplay = (nextProps) => {
// Null check is needed here as 0 is a valid value
if (nextProps.activeIndex !== null && nextProps.activeIndex === this.props.index) {
this.setState({
showCounter: !this.state.showCounter
});
} else if (nextProps.activeIndex !== null && nextProps.activeIndex !== this.props.index) {
this.setState({
showCounter: false
});
}
}
componentWillReceiveProps(nextProps) {
console.log('nextProps: ', nextProps)
}
render() {
const serverUrl = getServerAddress();
const {product} = this.props;
const price = product.iogmodPrice ? product.iogmodPrice : product.price;
const isExpanded = product.id === this.props.expandedViewId;
const imageSrc = product.imageName
? 'https://b2b.martinsmart.com/productimages/'+ product.imageName.replace("Original", "Thumbnail")
: serverUrl + '/b2b/resources/images/nophoto.gif';
return (
<View style={styles.pContainer}>
<CartProduct
imageName={imageSrc}
name={product.description}
itemNum={product.id}
price={price}
pack={product.pack}
averageWeight={product.averageWeight}
cases={product.order_count}
/>
<TouchableOpacity style={styles.buttonContainer} onPress={() => this.expandCartProductItem(product.id)}>
{isExpanded ? <LineIcon name="arrow-up" style={styles.arrowIcon} /> : <LineIcon name="arrow-down" style={styles.arrowIcon} />}
</TouchableOpacity>
{isExpanded &&
<ExpandHeightView height={70}>
<View style={styles.counterContainerView}>
<QuantityCounter style={{width: '100%'}} product={product} />
</View>
</ExpandHeightView>
}
</View>
);
}
}
Here is the parent component function that passes the id to the action and the initial const declarations in the render:
expandAndCollapseItems = (id) => {
this.props.dispatch(collapseCartItemViews(id));
}
render() {
const {isLoading, displayDetails, sortCasesAsc, details, items, expandedItem} = this.props.orderInfo;
Here is the child component in the parent component where the expandedItem variable is being passed into it:
<FlatList
data={items}
keyExtractor={(item, index) => item.id.toString()}
renderItem={({item}) => <CartProductItem product={item} expandedViewId={expandedItem} onExpandClick={(id) => this.expandAndCollapseItems(id)} />}
/>
Finally, here is the reducer function updates the app state:
case types.SET_EXPANDED_STATE:
const id = action.id;
return {
...state,
expandedItem: id
}
Since you're using redux, you can just grab the expanded item id from the redux store in the child instead of passing it down from the parent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With