title: Redux not Re-rendering React components even though store is updated
body: <p>Hi I'm new to Redux and I'm using React and Redux to try to build a UI where I can drag and drop files (invoices in this case) into a portion of the UI, render them in a list and then be able to launch a popover to edit the metadata associated with each invoice.  Dragging and dropping is all working fine - Redux is re-rendering the view each time a file is dropped and the list is being updated. However, when I try an click the edit button against each invoice the store is being updated but the props in my popover component are not. Indeed, it doesn't look like any re-rendering is happening at all when I attempt to click the edit invoice button</p>
  
  <p>App.js</p>
  
  <pre><code>import React from 'react'
  import AddInvoice from '../containers/AddInvoice'
  import CurrentInvoiceList from '../containers/CurrentInvoiceList'
  import ControlPopover from '../containers/ControlPopover'
  
  const App = () =&gt; (
    &lt;div&gt;
      &lt;AddInvoice /&gt;
      &lt;CurrentInvoiceList /&gt;
      &lt;ControlPopover /&gt;
    &lt;/div&gt;
  )
  
  export default App
  </code></pre>
  
  <p>containers/AddInvoice.js</p>
  
  <pre><code>import React from 'react'
  import { connect } from 'react-redux'
  import { addInvoice } from '../actions'
  
  const recipientDataDefaults = {
    name: '',
    surname: '',
    address: '',
    phone: ''
  };
  
  const handleDragOver = event =&gt; {
    event.stopPropagation();
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';
  };
  
  const handleDragEnter = event =&gt; {
    event.stopPropagation();
    event.preventDefault();
  };
  
  const handleDragLeave = event =&gt; {
    event.stopPropagation();
    event.preventDefault();    
  };
  
  let AddInvoice = ({ dispatch }) =&gt;
    const styles = {'minHeight': '200px', 'background': 'tomato'}
    return (
      &lt;div style={styles}
           onDragEnter={handleDragEnter} 
           onDragLeave={handleDragLeave} 
           onDragOver={handleDragOver} 
           onDrop={event =&gt; {
             event.stopPropagation(); 
             event.preventDefault();
             const data  = event.dataTransfer;
             const files = data.files;
  
             const newInvoiceUploads = Object.keys(files)
               .map(key =&gt; files[key])
               .map(file =&gt; {
                 const invoiceObject = {};
                 invoiceObject.files = [file];
                 invoiceObject.recipientData = Object.assign({}, recipientDataDefaults);
                 return invoiceObject;
               });
  
             newInvoiceUploads.forEach(invoice =&gt; dispatch(addInvoice(invoice)))
  
      }}&gt;
        Drag an invoice here to upload
      &lt;/div&gt;
    )
  }
  AddInvoice = connect()(AddInvoice)
  
  export default AddInvoice
  </code></pre>
  
  <p>containers/ControlPopover.js</p>
  
  <pre><code>import { connect } from 'react-redux'
  import { closePopoverWithoutSave } from '../actions'
  import Popover from '../components/Popover/Popover'
  
  const mapStateToProps = (state) =&gt; {
    return {
      isActive: !!state.isActive
    }
  }
  
  const mapDispatchToProps = {
    handleCancel: closePopoverWithoutSave
  }
  
  
  const ControlPopover = connect(
    mapStateToProps,
    mapDispatchToProps
  )(Popover)
  
  export default ControlPopover
  </code></pre>
  
  <p>containers/CurrentInvoiceList.js</p>
  
  <pre><code>import { connect } from 'react-redux'
  import { showInvoiceEditPopover } from '../actions'
  import InvoiceList from '../components/InvoiceList/InvoiceList'
  
  const mapStateToProps = state =&gt; {
    return {
      invoices: state.invoices
    }
  }
  
  const mapDispatchToProps = dispatch =&gt; ({
    handleEditInvoice: invoice =&gt; {
      dispatch(showInvoiceEditPopover(invoice))
    }
  })
  
  const CurrentInvoiceList = connect(
    mapStateToProps,
    mapDispatchToProps
  )(InvoiceList)
  
  export default CurrentInvoiceList
  </code></pre>
  
  <p>actions/index.js</p>
  
  <pre><code>let nextInvoiceId = 0
  export const addInvoice = invoice =&gt; ({
    type: 'ADD_INVOICE',
    id: nextInvoiceId++,
    invoiceData: invoice
  })
  
  export const showInvoiceEditPopover = invoice =&gt; ({
    type: 'SHOW_POPOVER',
    invoice
  })
  </code></pre>
  
  <p>The popover reducer (combined in app but inlined here for brevity) reducers/index.js</p>
  
  <pre><code>const popover = (state = {}, action) =&gt; {
    switch (action.type) {
      case 'SHOW_POPOVER':
        const popoverState = {}
        popoverState.isActive = true
        popoverState.data = action.invoice
        return popoverState
  
       case 'CLOSE_POPOVER_WITHOUT_SAVING':
         const inactiveState = {}
         inactiveState.isActive = false
         inactiveState.data = {}
         return inactiveState;
       default:
         return state
     }
  }
  
  export default popover
  </code></pre>
  
  <p>components/InvoiceList.js</p>
  
  <pre><code>import React from 'react'
  import PropTypes from 'prop-types'
  import Invoice from '../Invoice/Invoice'
  
  const InvoiceList = ({ invoices, handleEditInvoice }) =&gt; {
  
  return (
    &lt;div&gt;
      {invoices.map(invoice =&gt;
        &lt;Invoice
          key={invoice.id}
          invoice={invoice.invoiceData}
          onClick={event =&gt; {
            // here we invoke the action bound by the CurrentInvoiceList
            // container
            event.preventDefault()
            handleEditInvoice(invoice)
          }}
        /&gt;
      )}
    &lt;/div&gt;
   )
  }
  
  InvoiceList.propTypes = {
    invoices: PropTypes.arrayOf(PropTypes.shape({
      id: PropTypes.number.isRequired,
      invoiceData: PropTypes.object
    }).isRequired).isRequired,
    handleEditInvoice: PropTypes.func.isRequired
  }
  
  export default InvoiceList
  </code></pre>
  
  <p>components/Invoice.js</p>
  
  <pre><code>import React from 'react'
  import PropTypes from 'prop-types'
  import TextInput from '../TextInput/TextInput';
  import Button from '../Button/Button';
  import './invoice.css'
  
  const Invoice = ({ invoice, onClick }) =&gt; {
  
  const fileNames = invoice.files.map((file, index) =&gt; {
      return (&lt;div key={index} className="invoice__file-title-legend"&gt;
     {file.name}&lt;/div&gt;);
    });
  
  return (
      &lt;div className="invoice"&gt;
      &lt;form className="invoice__form"&gt;
      &lt;TextInput id="invoice__input-amount" placeholder="enter invoice amount" label="Invoice Amount" /&gt;
      &lt;TextInput id="invoice__input-target" placeholder="enter payment target" label="Payment Target" /&gt;
      &lt;Button value="Add recipient" onClick={onClick} /&gt; // clicking this button updates the store but does NOT re-render. Why?
    &lt;/form&gt;
  
    &lt;div className="invoice__files"&gt;{fileNames}&lt;/div&gt;
  &lt;/div&gt;
    )
  }
  
  Invoice.propTypes = {
    onClick: PropTypes.func.isRequired,
    invoice: PropTypes.object
  }
  
  export default Invoice
  </code></pre>
  
  <p>components/Popover/Popover.js</p>
  
  <pre><code>import React from 'react'
  import PropTypes from 'prop-types'
  import createModifiers      from '../../lib/createModifiers';
  import './Popover.css';
  
  const Popover = ({ handleCancel, isActive }) =&gt; {
    console.log('rendering popover component') // does not get called when invoice edit button is pressed
    const popoverModifiers = createModifiers('popover', {
      'is-active': isActive
    })
  
    return (
      &lt;div className={popoverModifiers}&gt;
        &lt;div className="popover__header"&gt;
          &lt;button onClick={handleCancel}&gt;x&lt;/button&gt;
        &lt;/div&gt;
        &lt;div className="popover__content"&gt;
         Popover content
        &lt;/div&gt;
      &lt;/div&gt;
    )
  }
  Popover.propTypes = {
    handleCancel: PropTypes.func.isRequired,
    isActive: PropTypes.bool.isRequired 
  }
  
  export default Popover
  </code></pre>
  
  <p>And finally the createModifiers Code for posterity. This code is merely producing some BEM modifier CSS classes based on a state boolean value passed in</p>
  
  <pre><code>const createModifiers = (element, modifiers) =&gt; {
    const classList = Object.keys(modifiers)
      .filter(key =&gt; modifiers[key])
      .map(modifier =&gt; `${element}--${modifier}`)
      .concat(element)
      .join(' ')
  
    return classList
  }
  
  export default createModifiers
  </code></pre>
  
  <p>I know this is a large amount of example code so I tried to keep it a brief and focused as possible whilst giving a comprehensive view of the application. Any help is most appreciated.</p>