Попытка заставить список задач обновляться каждый раз, когда вводится новое задание

#javascript #reactjs #flux

#javascript #reactjs #поток

Вопрос:

Я создаю базовое приложение todo в react с flux. Я пытаюсь сделать так, чтобы каждый раз, когда в API вводится новое задание, список обновлялся в режиме реального времени, а не мне приходилось перезагружать страницу, а приложение делало другой запрос. Я пробовал использовать componentDidUpdate; однако, похоже, в данном случае это не работает. Как мне это реализовать?

Мой Todos.js

 import React from "react";

import * as TodoActions from "../actions/TodoActions";
import TodoStore from "../stores/TodoStore";
import './Todos.css'


export default class Todos extends React.Component {
  constructor() {
    super();
    this.addItem = this.addItem.bind(this);
    this.deleteTodo = this.deleteTodo.bind(this)
    this.getTodos = this.getTodos.bind(this);
    this.state = {
      todos: TodoStore.getAll(),
    };
    TodoActions.receiveTodos()
  }

  componentWillMount() {
    TodoStore.addChangeListener(this.getTodos);
  }

  componentWillUnmount() {
    TodoStore.removeChangeListener(this.getTodos);
  }

  componentDidMount() {
    TodoActions.receiveTodos();
  }

  componentDidUpdate() {
    TodoActions.receiveTodos();
  }

  getTodos() {
    this.setState({
      todos: TodoStore.getAll(),
    });
  }


  deleteTodo(id) {
    TodoActions.deleteTodo(id);
    }

  addItem(e) {
    e.preventDefault();
    TodoActions.createTodo(this._inputElement.value)
  }

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

    const TodoComponents = todos.map((todo) => {
        return (
          <div key={todo.id} className="todo-list">
            <div className="todo-name">{todo.name}</div>
            <div className="todo-btn"><button type="button" onClick={() => this.deleteTodo(todo.id)}>Delete</button></div>
          </div>
        )
    });

    return (
      <div className="main-container">
        <h1 className="title">Todos</h1>
        <ul>{TodoComponents}</ul>
        <form onSubmit={this.addItem}>
          <input ref={(a) => this._inputElement = a} placeholder="Enter Task" className="input-form"/>
          <button type="submit" className="input-btn">Add</button>
        </form>
      </div>
    );
  }
} 
  

Мой TodoStore.js

 import { EventEmitter } from "events";

import AppDispatcher from "../dispatcher";

let _todos = []

function setTodos(todos) {
  _todos = todos;
}

class TodoStore extends EventEmitter {

  emitChange = () => {
    this.emit("change");
  }

  addChangeListener = (callback) => {
    this.on("change", callback)
  }

  removeChangeListener = (callback) => {
    this.removeListener("change", callback)
  }

  getAll = () => {
    return _todos;
  }

  handleActions = (action) => {
    switch(action.type) {
      case "RECEIVE_TODOS": {
        setTodos(action.todos);
        this.emit("change")
        break;
      }
    }

  }

}

const todoStore = new TodoStore;
AppDispatcher.register(todoStore.handleActions.bind(todoStore));
export default todoStore;
  

Мой TodoActions.js

 import AppDispatcher from "../dispatcher";
import apiClient from "../api-client"

export function createTodo(name) {
  apiClient.createTodo({name: name}).then((result) => {
    AppDispatcher.dispatch({
      type: "CREATE_TODO",
      name: result,
    });
  })
}

export function deleteTodo(id) {
  apiClient.deleteTodo(id).then((result) => {
    AppDispatcher.dispatch({
      type: "DELETE_TODO",
      id,
    });
  })
}


export function receiveTodos() {
  apiClient.getAllTodos().then(result => {
    AppDispatcher.dispatch({
      type: "RECEIVE_TODOS",
      todos: result.payload
    });
  })
}
  

Комментарии:

1. Первый вариант, похоже, не работает. Как я мог бы попробовать второе?