Отправление не является функцией реагировать - PullRequest
0 голосов
/ 19 марта 2019

Я работаю над приложением, использующим реаги и редуксы Я использую API.

поток приложения:

  • заполните форму,
  • нажмите кнопку отправки,
  • отправка данных из формы в API,
  • перейти на страницу рецептов

Первый компонент - это форма, в которую вы вводите информацию (название, калории, тип рациона).

    class FormPage extends Component {
      constructor(props) {
        super(props);

        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.goToListOfMealPage = this.goToListOfMealPage.bind(this);
      }

      handleFormSubmit(data) {
        const name = data.name;
        const calories = data.caloreis;
        const diet = data.diet;
        const health = data.health;

        console.log(name)
        return loadData( name, calories, diet, health)()
          .then(({ error }) => {
            if (!error) {
              setTimeout(this.goToListOfMealPage, 1500);
            }

            return error;
          }
        );
      }

      goToListOfMealPage() {
        const { history } = this.props;
        history.push('/ListMeal');
      }

      render() {
        return (
          <Form onSubmit={this.handleFormSubmit}/>
        );
      }
    }

const mapDispatchToProps = (dispatch) => {
  return {
    loadData: () => dispatch(loadData())
  }
};

FormPage = connect(mapDispatchToProps)(FormPage)
export default FormPage;

handleFromSubmit функция для отправки данных формы по ссылке API (https://api.edamam.com/search?q=${name}n&app_id=${key.id}&app_key=${key.key}&calories=${calories}&health=${health}&diet=${diet}).

После заполнения формы и нажатия кнопки «Отправить» я хочу разместить список блюд (рецептов) на новой подстранице.

, где loadData равно

const fetchDataStart = () => ({
  type: actionTypes.FETCH_DATA_START,
});

const fetchDataSucces = (data) => ({
  type: actionTypes.FETCH_DATA_SUCCESS,
  data,
});

const fetchDataFail = () => ({
  type: actionTypes.FETCH_DATA_FAIL,
});

const loadData = (name, calories, diet, health) => (dispatch) => {
  dispatch(fetchDataStart());
  return axios.get(`https://api.edamam.com/search?q=${name}n&app_id=${key.id}&app_key=${key.key}&calories=${calories}&health=${health}&diet=${diet}`)
    .then(({ data }) => console.log(data) || dispatch(fetchDataSucces(data)))
    .catch((err) => dispatch(fetchDataFail(err.response.data)));
};

После отправки формы я получаю сообщение об ошибке TypeError: dispatch is not a function

enter image description here

Не могу найти причину этой ошибки

Ответы [ 2 ]

3 голосов
/ 19 марта 2019

Есть некоторые проблемы с вашим кодом:

  • Если вы сопоставили отправку с подпоркой, вы можете вызвать действие, выполнив this.props.loadData(params)
  • Вы не должны вызывать действие, выполняя это loadData()(), поскольку отправленное действие не возвращает функцию (не позволяйте этому обмануть вас, хотя исходное действие возвращает функцию).

Итак, чтобы использовать действие loadData(), вам необходимо сопоставить его с реквизитом следующим образом:

const mapDispatchToProps = dispatch => ({
  loadData: (name, calories, diet, health) => dispatch(loadData(name, calories, diet, health)),
});

Тогда используйте это так:

componentDidMount() {
  this.props.loadData(name, calories, diet, health)
    .then(() => console.log('Success'))
    .catch(err => throw new Error("Error", err.stack))
}

Редактировать: Исходя из вашего вновь отредактированного вопроса, функция соединения в redux принимает mapStateToProps и mapDispatchToProps соответственно, поэтому в вашем коде должно быть:

export default connect(null, mapDispatchToProps)(Component)
1 голос
/ 19 марта 2019
  1. Ваш конструктор не нужен - вы можете автоматически связать функции таким образом.

  2. Если в компоненте нет mapStateToProps, оставьте его пустым.

РЕДАКТИРОВАННЫЙ КОД:

import React from 'react';
// Your imports

class FormPage extends Component {
  handleFormSubmit = (data) => {
    const { name, caloreis, diet, health } = data;
    this.props.loadData(name, caloreis, diet, health);
  }

  goToListOfMealPage = () => {
    const { history } = this.props;
    history.push('/ListMeal');
  }

  render() {
    return (
      <Form onSubmit={this.handleFormSubmit} />
    );
  }
}

const mapDispatchToProps = dispatch => ({
  loadData: (name, caloreis, diet, health) => dispatch(loadData(name, caloreis, diet, health))
});

export default connect(null, mapDispatchToProps)(FormPage);

Предложение по перенаправлению:

  1. Вы должны поддерживать успешность и ошибку отправки в избыточном состоянии, в случае успеха - вы можете перенаправить на goToListOfMealPage - вы можете сделать это в componentWillReceiveProps. Мы должны сделать что-то похожее на код ниже:
class FormPage extends Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.formSubmitSuccess !== nextProps.formSubmitSuccess && nextProps.formSubmitSuccess) {
      this.goToListOfMealPage()
    }
  }
  //... rest of the code.
}

// Your map state to props:
const mapStateToProps = state => ({
  formSubmitSuccess: state.reducerIdentifier.formSubmitSuccess,
  formSubmitFailure: state.reducerIdentifier.formSubmitFailure
});
...