Почему метод возвращает [object Object]?

Рейтинг: 0Ответов: 2Опубликовано: 18.05.2023

Есть метод checkWinner который который срабатывает при клике на компонент <ButtonResult checkWinner={this.checkWinner}/>. Данный метод находить находить наибольшее значение ключа в объекте this.state и выводит в консоль. Проблема заключается в том что выводит {"[object Object]":1}, а вместо [object Object] должен быть id к примеру voute1

Main.js:

export default class Main extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            vote1: 0,
            vote2: 0,
            vote3: 0,
            vote4: 0,
            vote5: 0,
        }
        this.increaseVote = this.increaseVote.bind(this);
        this.checkWinner = this.checkWinner.bind(this);
    }
    increaseVote(id) {
        return this.setState(state => {
            console.log({[id]: state[id]});
            return {
                [id]: state[id] + 1
            }
        })
    }
    checkWinner(id) {
        console.log(typeof id)
        console.log(id)
        console.log(typeof{[id]: Math.max(...Object.values(this.state))})
        console.log({[id]: Math.max(...Object.values(this.state))})
        return this.setState(state => {
            return JSON.stringify({
                [id.toString()]: Math.max(...Object.values(state))
            })
        })
    }
  render() {
    return (
        <Wrapper>
          <List>
            <Item text="&#128540;" id="vote1" increaseVote={this.increaseVote} state={this.state}/>
            <Item text="&#128520;" id="vote2" increaseVote={this.increaseVote} state={this.state}/>
            <Item text="&#128640;" id="vote3" increaseVote={this.increaseVote} state={this.state}/>
            <Item text="&#128526;" id="vote4" increaseVote={this.increaseVote} state={this.state}/>
            <Item text="&#128566;" id="vote5" increaseVote={this.increaseVote} state={this.state}/>
          </List>
          <ButtonResult checkWinner={this.checkWinner}/>
          <Winner/>
        </Wrapper>
    )
  }
}

Winner.js:

export default class Winner extends React.Component {
    render() {
        return (
            <div className="block-winner"></div>
        )
    }
}

Item.js:

export default class Item extends React.Component {
    render() {
        const { id, text, state, increaseVote } = this.props;
        const onClick = () => increaseVote(id);
        return (
            <li>
                <Button onClick={onClick} id={id} text={text}/>
                <Count text={state[id]}/>
            </li>
        )
    }
}

**ButtonResult.js: **

export default class ButtonResult extends React.Component {
    render() {
        const { checkWinner } = this.props;
        return (
            <button onClick={checkWinner} className="button-result">Result</button>
        )
    }
}

Button.js:

export default class Button extends React.Component {
    render() {
            const { id, text, onClick } = this.props;
        return (
            <button onClick={onClick} className="button" id={id}>{text}</button>
        )
    }
}

Count.js:

export default class Count extends React.Component {
    render() {
        const { text } = this.props;
        return (
            <p className="count-click">{text}</p>
        )
    }
}

List.js:

export default class List extends React.Component {
    render() {
        return (
            <ul className="list-buttons" id="listButtons">{this.props.children}</ul>
        )
    }
}

Wrapper.js:

export default class Wrapper extends React.Component {
    render() {
        return (
            <div className="wrapper">{this.props.children}</div>
        )
    }
}

Ответы

▲ 1Принят

Два варианта решения проблемы. Все зависит от задачи.

  1. в Main.js модифицировать методы increaseVote и checkWinner, которые в качестве аргумента будут принимать SyntheticEvent (этот аргумент возникает в button.onclick в компоненте Button), в нем есть поле target, оно ссылается на элемент в котором произошло событие click, и указывает на button в DOM дереве. С него нужно взять id. Код для increaseVote будет выглядеть так:
 increaseVote(event) {
      const id = event.target.id;
      return this.setState(state => {
        console.log({
          [id]: state[id]
        });
        return {
          [id]: state[id] + 1
        }
      })
    }
  1. Или изменить вызов функции onClick компоненте Button передав в качестве аргумента id. Код для Button будет выглядеть так:
export default class Button extends React.Component {
  render() {
    const {id, text, onClick} = this.props;
    return (
      <button onClick={() => onClick(id)} className="button" id={id}>{text}
      </button>
    )
  }
}
▲ 0

обработчик onlick первым параметром принимает объект события.

Соответственно здесь

<button onClick={checkWinner}

в метод checkWinner передается не id, а объект события о нажатии кнопки.