title: How to reuse the same Redux Saga for multiple React components with their own state?
body: <p>This is a bit of a lengthy one to explain. As briefly as possible: I have two components, <code>Employees</code> and <code>AddEmployee</code> - these are both attached to the routes <code>/employees</code> and <code>employees/add</code> respectively. A link from the <code>Employee</code> component will push <code>employees/add</code> to BrowserHistory, and vice versa (the <code>AddEmployee</code> component will also push <code>/employees</code> if the form is successfully submitted, or if the user clicks 'cancel').</p>
  
  <p>If I navigate to <code>/employees</code>, the component works fine. If I click to navigate to <code>/employees/add</code>, <em>that</em> component works fine. If I click 'cancel' or submit the form to redirect back to <code>/employees</code>... the component breaks.</p>
  
  <p>Through much debugging I've determined that this is because redux state for <code>AddEmployee</code> is persisting through to <code>Employee</code>. My guess would be this is because they both make use of the same saga. I've written a single <code>get</code> Redux saga to handle requests to the remote API. <code>Employees</code> obviously uses the <code>get</code> saga to retrieve all users, while <code>AddEmployee</code> uses the <code>get</code> saga to retrieve possible locations to assign the user to.</p>
  
  <p>When <code>Employees</code> is loaded, the state of the <code>apiGet</code> saga contains the retrieved employees. When <code>AddEmployee</code> is loaded, the state of the <code>apiGet</code> saga contains the retrieved locations. When you then navigate <em>back</em> to <code>Employees</code>, the state of the <code>apiGet</code> saga <em>still</em> contains the retrieved locations and it does not run again to load the employees again.</p>
  
  <p>How can I solve this?</p>
  
  <p>I've done my best to condense the code below to the relevant portions.</p>
  
  <p>The <code>get</code> Saga:</p>
  
  <pre><code>function getApi(endpoint, token) {
      return fetch(apiUrl + endpoint, {
          method: 'GET',
          headers: {
              'Content-Type': 'application/json',
              'Authorization': 'Bearer ' + token
          }
      }).then(handleApiErrors)
        .then(response =&gt; response.json())
        .catch((error) =&gt; {throw error})
  }
  
  function* apiGetFlow(endpoint) {
      let response, token
      try {
          token = localStorage.getItem('token')
          token = JSON.parse(token)
  
          response = yield call(getApi, endpoint, token)
  
          yield put({ type: CLIENT_GET_SUCCESS, response: response })
  
      } catch(error) {
          ...
      }
  
      return response
  }
  
  function* apiGetWatcher() {
      while(true) {
          const { endpoint } = yield take(CLIENT_GET_REQUESTING)
          const task = yield fork(apiGetFlow, endpoint)
      }
  }
  
  export default apiGetWatcher
  </code></pre>
  
  <p>The <code>Employees</code> component:</p>
  
  <pre><code>class Employees extends Component {
  
      componentDidMount() {
          this.usersGet()
      }
  
      usersGet() {
          this.props.apiGetRequest('users')
      }
  
      render() {
          ...
      }
  }
  
  const mapStateToProps = state =&gt; {
      return {
          users: state.apiGet,
      }
  }
  
  const connected = connect(mapStateToProps, { apiGetRequest })(Employees)
  
  export default connected
  </code></pre>
  
  <p>The <code>AddEmployee</code> component:</p>
  
  <pre><code>class AddEmployeeForm extends Component {
  
      componentDidMount() {
          this.locationsGet()
      }
  
      locationsGet() {
          this.props.apiGetRequest('locations')
      }
  
      render() {
          ...
      }
  }
  
  const mapStateToProps = state =&gt; {
      return {
          locations: state.apiGet,
          save: state.apiPost,
      }
  }
  
  const formed = reduxForm({
      form: 'addemployee',
  })(AddEmployeeForm)
  
  const connected = connect(mapStateToProps, { apiGetRequest, apiPostRequest })(formed)
  
  export default connected
  </code></pre>