appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.9k stars 466 forks source link

Dispatching redux actions from ReactiveList#onData component #234

Closed fones closed 6 years ago

fones commented 6 years ago

Issue Type: I think this is a BUG.

Description: When trying to dispatch actions from a component that is rendered inside ReactiveList#onData, given action is not reaching reducers and redux store.

Code:

 <ReactiveList 
  componentId="SearchResult"
  dataField="domain"
  pagination={true}
  paginationAt="bottom"
  pages={5}
  sortBy="desc"
  size={10}
  loader="Loading Results..."
  showResultStats={true}
  onData={(res) => (
    <WebsiteCard res={res} key={res.domain} />
  )}
  onResultStats={(total, took) => {
    return "found " + total + " results in " + took + "ms."
  }}
  react={{
    and: ["search", "technology", "language", "social", "alexa"]
  }}/>
import React, { Component } from 'react';
import { connect } from 'react-redux'

let WebsiteCard = ({res, dispatch}) => (
  <div className="card mb-3" key={res.domain}>
    <div className="card-body">
      <h5 className="card-title">{res.domain}</h5>
      <h6 className="card-subtitle mb-2 text-muted">{res.meta.title}</h6>
      <p className="card-text">{res.meta.description}</p>
      <a href={`http://${res.domain}`} target="_blank" className="card-link">website</a>
      <a href='#' target="_blank" className="card-link" onClick={(e) => {
        e.preventDefault()
        dispatch({
          type: "ADD_EMAIL"
        })
      }}>
        emails ({res.emailsCount})
      </a>
    </div>
  </div>
)

export default connect()(WebsiteCard)

Minimal reproduction of the problem with instructions:

  1. Create separate component that is rendered inside onData method of ReactiveList
  2. Try dispatch actions.

Reactivesearch version: 2.2.0

Browser: all

Anything else: Actions dispatched from components outside reactive components are working properly.

fones commented 6 years ago

I have just found that you are using your own redux inside, and my component is connected to your store.

Any way to use redux in my case?

divyanshu013 commented 6 years ago

The reactivesearch Provider is over-writing the store in the context in case of nesting. @metagrover check out the example app I built with reactivesearch and redux at https://github.com/divyanshu013/reactivesearch-redux-example. The app will work if the ReactiveBase component here is moved to the top level (and surround the Provider). However in such cases, the Reactivesearch components won't receive the context object correctly from the ReactiveBase.

One possible solution I see here is that we pass the store object explicitly in Reactivesearch (not via context) which will prevent interference with the context in any user app. What do you think?

metagrover commented 6 years ago

yes, exactly my thoughts. We can maybe use combineReducers here to achieve this. Will test it with your app here!

divyanshu013 commented 6 years ago

Thanks @fones, fixed the issue on dev branch. The fix should be out in the coming release 👍

metagrover commented 6 years ago

Released in v2.2.1 🎉