обновление состояния для вложенного массива (отношение «один ко многим») без необходимости обновлять страницу sh - PullRequest
0 голосов
/ 09 июля 2020

В моем проекте у пользователя может быть много бюджетов, и каждый бюджет может иметь много расходов. Я использую бэкэнд Ruby on Rails и выполняю выборку на localhost с моим интерфейсом React. js. Я хочу иметь возможность создавать, обновлять и удалять как бюджеты, так и расходы. Итак, запрос POST работает и возвращает что-то вроде этого:

[
{
"id": 1,
"category": "transport",
"amount": 200,
"user_id": 1,
"expenses": [
{
"id": 127,
"budget_id": 1,
"description": "transport expense",
"date": null,
"amount": 20,
"created_at": "2020-07-09T06:15:50.287Z",
"updated_at": "2020-07-09T06:15:50.287Z"
}
]
},
{
"id": 4,
"category": "a new budget",
"amount": 200,
"user_id": 1,
"expenses": []
},
{
"id": 5,
"category": "new budget",
"amount": 2000,
"user_id": 1,
"expenses": [
{
"id": 125,
"budget_id": 5,
"description": "new expense",
"date": null,
"amount": 30,
"created_at": "2020-07-09T06:15:34.533Z",
"updated_at": "2020-07-09T06:15:34.533Z"
},
{
"id": 126,
"budget_id": 5,
"description": "another new exp",
"date": null,
"amount": 30,
"created_at": "2020-07-09T06:15:43.071Z",
"updated_at": "2020-07-09T06:15:43.071Z"
}
]
}
]

Мое дерево компонентов выглядит примерно так:

введите описание изображения здесь

Хотя я могу удалять вещи из бэкэнда, элементы (бюджет / расходы) не удаляются, пока я не обновлю sh страницу. У меня есть следующая функция в бюджете. js, чтобы вычесть общие суммы расходов из бюджетов (которые должны обновляться всякий раз, когда расходы добавляются / удаляются / обновляются, что происходит только после того, как я обновляю sh):


  handleBudgetChange = () => {
    let total = 0

    total = this.state.expense.reduce(
      (prevValue, currentValue) => prevValue + currentValue.amount, 0);
    let budgetRemaining = this.props.budget.amount - total 

    this.setState({
      remainingBudget: budgetRemaining
    })
  }

У меня есть состояние бюджета, проживающего в приложении. js и состояние расходов, проживающих в бюджете. js (также состояние расходов установлено равным параметрам бюджета --- - это потому, что мне нужно было иметь возможность сопоставить созданные расходы с соответствующим бюджетом, и по какой-то причине это не сработало бы по-другому).

Если у кого-то есть ЛЮБЫЕ СОВЕТЫ, как это исправить проблема .. Я застрял на нем несколько дней. Я также не очень знаком с реакцией (и не знаком с хуками и редукцией), поэтому любая помощь будет очень признательна. Я буду рад предоставить любую дополнительную информацию / код, если это необходимо. Спасибо!

Ответы [ 2 ]

0 голосов
/ 09 июля 2020

Вы должны обновить свое локальное состояние budgets и expenses после получения ответа от сервера операции CRUD.

Следующий пример кода может вам помочь

Приложение js

class App extends Component {
    constructor() {
        this.state = {
            budgets: []
        };
        this.handleBudgetChange.bind(this);
    }

    render() {
        return (
            <div>
                <Expense onBudgetsChange={this.handleBudgetChange} />
                {/* rest of your code */}
            </div>
       );
    }

    handleBudgetChange(budgets) {
        this.setState({
            budgets: budgets
        });
    }
}

Расходы. js

class Expense extends Component {
    constructor() {
        this.state = {
            expenses: []
        };
        this.handleBudgetDelete.bind(this);
        this.handleExpenseDelete.bind(this);
    }

    render() {
        return (
            <div>
                {/* your render logic */}
                <button onClick={this.handleBudgetDelete}>Delete Budget</button>
                <button onClick={this.handleExpenseDelete}>Delete Expense</button>
                {/* rest of your code */}
            </div>
        );
    }

    async handleBudgetDelete(id) {
        // call api and get updated budgets list
        const response = await api('/url-to-delete-budgets', id);
        this.props.onBudgetsChange(response); // notify parent component to update state
    }

    async handleExpenseDelete(id) {
        // call api to delete expense
        await api('/url-to-delete-expense', id);
        // update local state
        this.setState({
            expenses: this.state.expenses.filter(e => e.id !== id)
        });
    }
}
0 голосов
/ 09 июля 2020

Из вашей проблемы я понял, что вы хотите показать обновленный бюджет / расходы без обновления страницы. Итак, вот мои предложения -

  1. Без дополнительных вызовов API -

    • Обработка во внешнем интерфейсе - Вам необходимо обновить свое состояние реакции после добавления / обновления / удаления расходов или бюджета. Это не связано с дополнительным вызовом API. Вам нужно написать logi c во фронтенде, чтобы обновить ваше состояние. Это может быть hecti c, если у вас есть объекты с высокой степенью вложенности.
    • Отправить обновленные значения в ответе api - Вы можете отправить обновленные значения в своем ответе api POST / PUT / DELETE и в интерфейсе просто используйте этот ответ для обновления своего состояния.
  2. Сделайте дополнительный вызов API - После выполнения действия добавления / удаления / обновления (возможно, вы вызываете любой api PUT / POST / DELETE), вызовите тот же самый API GET, который вы вызываете для первоначального получения данных. С помощью этого ответа GET api просто обновите состояние.

...