Есть ли способ сохранить ссылку на компонент в состоянии? Или более «реактивная» альтернатива?

#reactjs #jsx

#reactjs #jsx

Вопрос:

Я пишу игру «пары», и мне нужно сохранить ссылки двух компонентов щелкнутой карты в родительском состоянии, чтобы я мог «перевернуть» их обратно при нажатии на третью карту. Есть ли способ сохранить ссылки в состоянии, которое будет доступно?

Итак, у меня есть сетка 4×4 на 16 карточек, и я сначала попытался создать ссылку для каждой из карточек (a1, a2, a3, a4, b1 и т.д.) И передать эти ссылки компонентам. Это отлично работает для запуска методов на этих компонентах, но только тогда, когда я явно ввожу ссылку, например, flip (this.a1.current).

Однако я не могу сохранить эту ссылку где-либо еще, поэтому у меня не может быть состояния в родительском

 class Game extends Component {
  constructor(props) {
    super(props);
    this.state= {
     lefthand: this.a1.current;
  

Есть ли способ сохранить ссылку в состоянии для последующего использования?

 class Game extends Component {

  constructor(props) {
    super(props);
    this.a1= React.createRef();
    this.a2= React.createRef();
    this.a3= React.createRef();
    this.a4= React.createRef();
    //etc
    this.state= {
      leftHand: '',
      rightHand: '',
    };
  }

  setLeftHand = (card) => {
    this.setState ({
      leftHand: card
    })
  }

  setRightHand = (card) => {
    this.setState ({
      rightHand: card
    })
 }


  render() {
    return (
      <div className="Game">
        <table>
          <tbody>
            <tr>
              <Card setlh={this.setLeftHand}
                    ref={this.a1}
                    setrh ={this.setRightHand}
                    lh={this.state.leftHand}
                    rh={this.state.rightHand}
                    cardID={this.state.deck[0]}/>
              <Card setlh={this.setLeftHand}
                    ref={this.a2}
                    setrh ={this.setRightHand}
                    lh={this.state.leftHand}
                    rh={this.state.rightHand}
                    cardID={this.state.deck[1]}/>
              <Card setlh={this.setLeftHand}
                    ref={this.a3}
                    setrh ={this.setRightHand}
                    lh={this.state.leftHand}
                    rh={this.state.rightHand}
                    cardID={this.state.deck[2]}/>
              <Card setlh={this.setLeftHand}
                    ref={this.a4}
                    setrh ={this.setRightHand}
                    lh={this.state.leftHand}
                    rh={this.state.rightHand}
                    cardID={this.state.deck[3]}/>
            </tr>
  

(представьте себе еще 3 такие строки …)

           </tbody>
        </table>
      </div>
    )
  }
}

class Card extends Component {

  handleclick() {
    //if this is the first card drawn, addCardToLeftHand
  }

  addCardToLeftHand() {
    this.props.setlh(this.ref);
  }


  render() {
    if(this.state.backShowing) {
      return (<td onClick={this.handleclick}>xxxxxxxxxxx</td>)
    } else {
      return (<td onClick={this.handleclick}>{this.props.cardID}</td>)
    }
  }
}
  

Я хочу иметь возможность, например, запускать метод по ссылке, хранящейся в this.state .слева, а затем снова для this.state.справа.

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

Я просто хочу, чтобы addCardToLeftHand из компонента Card работал. Я упускаю что-то очевидное?

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

1. Это очень «jquery» способ мышления, попробуйте думать в переменных, которые будут хранить символическое состояние «isFlipped», а затем использовать это состояние с дочерним элементом «контролируемого компонента», чтобы обрабатывать, как это состояние просматривается и изменяется.

Ответ №1:

Сохраняйте все состояние игры в Game компоненте, включая состояние отдельных карт. Вы не должны сохранять какое-либо состояние, используя ссылки на компоненты, используйте вместо этого идентификаторы. Вы можете добавить onClick обратный вызов к Card компоненту, чтобы событие click могло быть перенаправлено на Game . Затем в Game.handleCardClick вы можете вычислить новое состояние игры на основе предыдущего состояния игры и события click. Кроме того, ваш текущий подход к управлению картами является ручным и подвержен ошибкам; рассмотрите возможность использования двумерного массива для хранения ваших карт и динамической генерации Card компонентов.

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

1. да, я знал, что способ, которым я управлял отдельными карточками, был немного пони, это был единственный способ, которым я мог вставить туда каждую ссылку. Я попробую это сделать, и тогда Марк решит! Спасибо!

2. Вы правы, я начал снова, сохраняя gamestate в game и программно создавая карты. Это сделало все намного проще.