0
votes

I have created an input field and am dispatching an action in the onChange method of the input field. i have a state attribute text:'' which should get updated once user starts typing in the input field but same is not happening , instead text attribute in the state disappears once action is fired as checked in Redux Dev tool.

Also have below 2 queries - read the docs , but still not clear

  1. Why do we have to pass initialState in createStore as I have already passed in state to reducers , though have passed empty initialState to createStore .

  2. Do I need to use mapStateToProps in my case as I am not making use of any state in my component

Action file - searchActions.js

import { SEARCH_MOVIE } from "./types";

export const searchMovie = text => ({
  type: SEARCH_MOVIE,
  payload: text
});

Reducer file - searchReducer.js

import { SEARCH_MOVIE } from "../actions/types";

const initialState = {
  text: ""
};

const searchReducer = (state = initialState, action) => {
  console.log(action);
  switch (action.type) {
    case SEARCH_MOVIE:
      return {
        ...state,
        text: action.payload
      };
    default:
      return state;
  }
};

export default searchReducer;

Root reducer file - index.js

import { combineReducers } from "redux";
import searchReducer from "./searchReducer";

const rootReducer = combineReducers({
  searchReducer
});

export default rootReducer;

Store file - store.js

import { createStore } from "redux";

import rootReducer from "./reducers";

const initialState = {};

const store = createStore(
  rootReducer,
  initialState,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

export default store;

Form containing the input field - SearchForm.js

import React, { Component } from "react";
import { searchMovie } from "../../actions/searchActions";

import { connect } from "react-redux";

export class SearchForm extends Component {
  onChange = e => {
    this.props.searchMovie(e.target.value);
  };
  render() {

    return (
      <div className="jumbotron jumbotron-fluid mt-5 text-center">
        <form className="form-group">


<input
        type="text"
        className="form-control"
        placeholder="Search Movies"
        onChange={e => this.onChange(e)}
      ></input>
      <button type="submit" className="btn btn-primary mt-3 btn-bg">
        Search
      </button>


         </form>
          </div>
        );
      }
    }

    const mapStateToProps = state => {
      return {
        text: state.text
      };
    };

    const mapDispatchToProps = dispatch => ({
      searchMovie: () => dispatch(searchMovie())
    });

    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(SearchForm);

Entry file - App.js

import React, { Component } from "react";
import { Provider } from "react-redux";

import SearchForm from "./SearchForm";
import store from "./store";

import "./App.css";

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <SearchForm />
      </Provider>
    );
  }
}

export default App;
1

1 Answers

0
votes

You call this function with a parameter

this.props.searchMovie(e.target.value);

However in here you do not provide any parameter

const mapDispatchToProps = dispatch => ({
    searchMovie: () => dispatch(searchMovie())
});

should be

const mapDispatchToProps = dispatch => ({
    searchMovie: movie => dispatch(searchMovie(movie))
});

For your questions

1. Why do we have to pass initialState in createStore as I have already passed in state to reducers , though have passed empty initialState to createStore .

You haven't passed initialState to reducer, in fact you can't. This is different const searchReducer = (state = initialState, action) => {. It's a javascript syntax which acts as a default value for a parameter if you don't provide one.

2. Do I need to use mapStateToProps in my case as I am not making use of any state in my component

Yes you don't have to. You can set is as undefined