Вызов одной функции в другой и передача ее идентификатору, реагирование + избыточность - PullRequest
0 голосов
/ 03 октября 2019

В самой React у меня есть функция getTodos(), в которой она вызывает другую функцию getTodo(). Он передает res.data[0].id в функцию getTodo().

Реакция

Демонстрация здесь: https://stackblitz.com/edit/react-qvsjrz

Код ниже:

class App extends Component {
  constructor() {
    super();
    this.state = {
      todos: [],
      todo: {}
    };
  }

  componentDidMount() {
    this.getTodos()
  }

  getTodos = () => {
    axios({
        url: 'https://jsonplaceholder.typicode.com/todos',
        method: 'GET'
    })
    .then(res => {
      this.setState({
        todos: res.data,
      }, () => this.getTodo(res.data[0].id))
    })  
    .catch(error => {
      console.log(error);
    });
  };

  getTodo = (todoId) => {
    axios({
      url: `https://jsonplaceholder.typicode.com/todos/${todoId}`,
      method: 'GET'
    })
    .then(res => {
      this.setState({
        todo: res.data
      })
    })
    .catch(error => {
      console.log(error);

    })
  }

  render() {
    console.log(this.state.todo);
    return (
      <div>

      </div>
    );
  }
}

Приведенный выше код пытается преобразовать в реагировать + избыточность.

реагировать + избыточность

В действиях я объявил две функции getTodo и getTodos. Может кто-нибудь посоветовать мне, как вызвать функцию getTodo в функции getTodos, передав функцию getTodo id?

Демонстрация здесь: https://stackblitz.com/edit/react-ewpquh?file=actions%2Findex.js

действия

   import axios from 'axios';

    export const GET_TODOS = 'GET_TODOS';
    export const FETCH_SUCCESS = 'FETCH_SUCCESS';
    export const FETCH_FAILURE = 'FETCH_FAILURE';

    export const getTodos = () => 
     dispatch => {

  return axios({
      url: 'https://jsonplaceholder.typicode.com/todos',
      method: 'GET',
    })
    .then(({data})=> {
      console.log(data);

      dispatch({type: GET_TODOS, payload:{
        data 
      }});   
    })
    .catch(error => {
      console.log(error);

      dispatch({type: FETCH_FAILURE})
    });
};

    export const getTodo = () => 
    dispatch => {


  return axios({
      url: 'https://jsonplaceholder.typicode.com/todos',
      method: 'GET',
    })
    .then(({data})=> {
      console.log(data);

      dispatch({type: GET_TODOS, payload:{
        data 
      }});   
    })
    .catch(error => {
      console.log(error);

      dispatch({type: FETCH_FAILURE})
    });
};

Todos

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {getTodos} from '../.././actions';

class Todos extends Component {
  componentDidMount() {
    this.props.getTodos(); 
  }

  render() {
    return (
      <ul>
        {this.props.todos.map(todo => {
        return <li key={todo.id}>
                  {todo.title}
               </li>
         })}
      </ul>
    );
  }
}

const mapStateToProps = state => {
  console.log(state.todos);
  const { todos } = state;

  return {
    todos
  };
};

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

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

редукторы

import {GET_TODOS} from '../../actions';

const initialState = {
  todos: []
};

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'GET_TODOS':
      return {
        ...state,
        todos: action.payload.data
      };

    default:
      return state;
  }
};

export default rootReducer;

магазин

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

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

export default store;

1 Ответ

3 голосов
/ 03 октября 2019

Вместо того, чтобы усложнять свои действия, у вас должны быть отдельные типы действий для разных API.

  1. GET_TODOS - для API / todos
  2. GET_TO - для / todos / API

Чтобы добавить getTodo метод с идентификатором, вот как я это решил -

  1. Для каждого тега li добавьте onClick, который вызывает ваш getTodo API. (Это сделано в качестве примера для добавления getTodo в рабочий процесс.
    return <li key={todo.id} onClick={() => this.handleClick(todo.id)}>
Добавить handleClick, который вызывает метод getTodo из реквизита.
  • Сначала добавьте getTodo в свои компоненты mapDispatchToProps:
    import { getTodo, getTodos} from '../.././actions';

    const mapDispatchToProps = dispatch => ({
      getTodos: () => dispatch(getTodos()),
      getTodo: id => dispatch(getTodo(id))
    });
  • Добавьте handleClick -

  handleClick = id => {
    this.props.getTodo(id).then(() => {
      console.log(`You Clicked: ${JSON.stringify(this.props.todo)}`)
    })
  }
Обновите действие getTodo, чтобы принять идентификатор в качестве ввода:

ПРИМЕЧАНИЕ. Добавленный тип GET_TODO

export const getTodo = (id) => dispatch => {

  return axios({
      url: `https://jsonplaceholder.typicode.com/todos/${id}`,
      method: 'GET',
    })
    .then(({data})=> {
      // console.log(data);
      dispatch({type: GET_TODO, payload: data});   
    })
    .catch(error => {
      console.log(error);

      dispatch({type: FETCH_FAILURE})
    });
};

Разделите ваши редукторы на todos и todo и используйте combineReducers из redux пакета -

const todos = (state = [], action) => {
  const { type, payload } = action;

  switch(type) {
    case 'GET_TODOS':
      return payload;
    default:
      return state;
  }
}

const todo = (state = {}, action) => {
  const { type, payload } = action;

  switch(type) {
    case 'GET_TODO':
      return payload;
    default:
      return state;
  }
}

const rootReducer = combineReducers({todos, todo});
Запустите приложение и щелкните любой элемент в списке задач. Журнал консоли для выбранного элемента задачи отображается при получении ответа API для этого идентификатора.

Здесь доступна живая песочница - https://stackblitz.com/edit/react-ndkasm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...