#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. Первый вариант, похоже, не работает. Как я мог бы попробовать второе?