0

I want a user be able to input text into an input box and based on this would like to search an api. I am using redux and redux-thunk. I am unsure how I should pass the text that is inputted as an argument to the API call.

If I wasn't using redux and thunk, I would set the state of the component as

this.state = {
    movie: ''
}

and then on the input type=text I would update the movie value onChange with e.target.value. What is the approach that should be taken when using react with redux?

My code looks like as follows.

import React, {Component} from 'react';
import {render} from 'react-dom';
import {createStore, applyMiddleware} from 'redux';
import {Provider, connect} from 'react-redux';
import thunk from 'redux-thunk';
import axios from 'axios';

function reducer(state = 0, action) {
  switch (action.type) {
    case 'GET_MOVIE':
      return action.data;
    default:
      return state;
  }
}

const store = createStore(
  reducer,
  applyMiddleware(thunk)
);


class App extends Component {

    getMovie(){
        this.props.getMovie();
    }

    render() {
        return(
            <div>
                <input type='text'>
                <input type='submit' onClick={this.props.getMovie}>
            </div>
        )
    }
}

function getMovie(movie){
    return function(dispatch) {
        axios.get('http://www.omdbapi.com/?t=' + movie)
        .then(function(data){
            dispatch(resolvedGetMovie(data.data));
        })
    }
}

function resolvedGetMovie(data){
    return {
        type: '
          GET_MOVIE ',
        data: data
    }
}

function mapStateToProps(state) {
    return {
        movie: state
    }
}

function mapDispatchToProps(dispatch) {
    return {
        getMovie : () => dispatch(getMovie())
    }
}

const ConnectedApp = connect(mapStateToProps, mapDispatchToProps)(App);

render(
    <Provider store={store}>
        <ConnectedApp />
    </Provider>,
    document.getElementById('root')
)

1 Answers1

1

When getting started with redux it's easy to get carried away and place all application state within reducers. But, for form fields, UI related state, and other state only relevant to a specific component, it can be beneficial to store this within the state of the component. For the example you provided, you should keep track of the input value in the state of the component and then pass that value to your action (getMovie)

For example:

class App extends Component {
    constructor(props) {
        this.state = {
            movie: ''
        }        
    }

    handleChange(e) {
        this.setState({
            movie: e.target.value
        });
    }

    handleSubmit() {
        const {movie} = this.state;
        this.props.getMovie(movie);
    }

    render() {
        const {movie} = this.state;

        return(
            <div>
                <input
                    type='text'
                    onChange={this.handleChange.bind(this)}
                    value={movie}
                />
                <input type='submit' onClick={this.handleSubmit.bind(this)}>
            </div>
        )
    }
}
alecrobins
  • 311
  • 2
  • 5