React JS, как обновить значение в массиве

Я новичок в React JS и сейчас работаю над школьным проектом. Это система подсчета очков для команд, всего 4 команды. В каждой команде по 5 детей. Теперь я создал массив с 5 счетчиками с идентификатором. 5 жетонов (количество) предназначены для детей. Я использую React в laravel. Мой код:

export default class Gryffindor extends Component {
    constructor(props) {
        super(props);
        this.state = { counters: [] };
        this.fetchCounters = this.fetchCounters.bind(this);
        this.counterIncrement = this.counterIncrement.bind(this);
        this.counterDecrement = this.counterDecrement.bind(this);
    }

    componentDidMount() {
        this.fetchCounters();
    }

    fetchCounters() {
        const counters = [
            { id: 1, amount: 0 },
            { id: 2, amount: 0 },
            { id: 3, amount: 0 },
            { id: 4, amount: 0 },
            { id: 5, amount: 0 }
        ];
        this.setState({ counters });
    }

    counterIncrement(e) {}

    counterDecrement() {
        if (counters.amount > 0) {
            this.setState({ counters: amount - 5 });
        }
    }

    render() {
        return <CounterBody counters = {this.state.counters} />;
    }
}

const CounterBody = ({ counters }) => (
    <table>
        <thead>
            <tr>
                <th />
                <th />
                <th />
            </tr>
        </thead>
        <tbody>
            {counters.map(counter => (
                <tr key = {counter.id}>
                    <td>
                        <button onClick = {this.counterDecrement}>Delete</button>
                    </td>
                    <td>{counter.amount}</td>
                    <td>
                        <button onClick = {this.counterIncrement}>Add</button>
                    </td>
                </tr>
            ))}
        </tbody>
    </table>
);

if (document.getElementById("Gryffindor")) {
    ReactDOM.render(<Gryffindor />, document.getElementById("Gryffindor"));
}

Я пытаюсь обновить сумму в счетчиках, но по идентификатору. Как видите, я пытался создать для него функции, но понятия не имел, что делать. Может кто поможет?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете получить доступ к this.counterDecrement или this.counterIncrement в компоненте Gryffindor из дочернего компонента. Вместо этого вам нужно передать эти функции как реквизиты.

Вы можете передать индекс счетчика функциям увеличения / уменьшения и обновить значение счетчика amount этим индексом.

Вы также можете поместить счетчики непосредственно в свое состояние вместо того, чтобы обновлять его в componentDidMount.

Пример

class Gryffindor extends React.Component {
  state = {
    counters: [
      { id: 1, amount: 0 },
      { id: 2, amount: 0 },
      { id: 3, amount: 0 },
      { id: 4, amount: 0 },
      { id: 5, amount: 0 }
    ]
  };

  counterIncrement = index => {
    this.setState(prevState => {
      const counters = [...prevState.counters];
      counters[index] = {
        ...counters[index],
        amount: counters[index].amount + 1
      };
      return { counters };
    });
  };

  counterDecrement = index => {
    this.setState(prevState => {
      const counters = [...prevState.counters];
      counters[index] = {
        ...counters[index],
        amount: counters[index].amount - 1
      };
      return { counters };
    });
  };

  render() {
    return (
      <CounterBody
        counters = {this.state.counters}
        onDecrement = {this.counterDecrement}
        onIncrement = {this.counterIncrement}
      />
    );
  }
}

const CounterBody = ({ counters, onDecrement, onIncrement }) => (
  <table>
    <thead>
      <tr>
        <th />
        <th />
        <th />
      </tr>
    </thead>
    <tbody>
      {counters.map((counter, index) => (
        <tr key = {counter.id}>
          <td>
            <button onClick = {() => onDecrement(index)}>Delete</button>
          </td>
          <td>{counter.amount}</td>
          <td>
            <button onClick = {() => onIncrement(index)}>Add</button>
          </td>
        </tr>
      ))}
    </tbody>
  </table>
);

ReactDOM.render(<Gryffindor />, document.getElementById("root"));
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id = "root"></div>

Вы должны структурировать свой код следующим образом ... Это прояснит, о чем вы просите

class Gryffindor extends React.Component {
    constructor() {
      state = {
        counters: [
          { id: 1, amount: 0 },
          { id: 2, amount: 0 },
          { id: 3, amount: 0 },
          { id: 4, amount: 0 },
          { id: 5, amount: 0 }
        ]
      };

      this.counterIncrement = this.counterIncrement.bind(this);
      this.counterDecrement = this.counterDecrement.bind(this);
    }

  counterIncrement(index) {
    this.setState(prevState => {
      const counters = [...prevState.counters];
      counters[index] = {
        ...counters[index],
        amount: counters[index].amount + 1
      };
      return { counters };
    });
  };

  counterDecrement(index) {
    this.setState(prevState => {
      const counters = [...prevState.counters];
      counters[index] = {
        ...counters[index],
        amount: counters[index].amount - 1
      };
      return { counters };
    });
  };

  render() {
    return (
      <CounterBody
        counters = {this.state.counters}
        onDecrement = {this.counterDecrement}
        onIncrement = {this.counterIncrement}
      />
    );
  }
}

Ваш вопрос довольно неясен, но чтобы найти его по идентификатору, у вас будет что-то вроде

deleteCertainCounter(e, passedInID) {
    this.setState({ counters: counters.filter(counter => counter.id !== passedInID) ]);
}

Спасибо за помощь!

14mble 05.11.2018 18:44

Другие вопросы по теме