Реагировать на передачу значения onClick из одного класса в другой - PullRequest
0 голосов
/ 28 апреля 2018

В Tournaments.js у меня есть список имен Турниров, каждое с уникальными идентификаторами, которые извлекаются из API. Теперь, когда я нажимаю на одно из этих названий турниров, я получаю его идентификатор, но мне нужно передать этот идентификатор в Template.js, где я могу получить данные турнира на основе выбранного идентификатора турнира. Я пытаюсь что-то сделать, передавая реквизит от ребенка к родителю, но сейчас я совершенно потерян.

Tournament.js:

import React, { Component } from "react";
import Template from './template';

const API = 'http://localhost:8080/api/tournaments';

class Tournaments extends Component {

  constructor() {
    super();
    this.state = {
      data: []
    }
  }

  componentDidMount() {
    fetch(API)
    .then((Response) => Response.json())
    .then((findresponse) => {
      console.log(findresponse)
      this.setState({
        data:findresponse,
      })
    })
  }

  reply_click(event) {
    var targetId = event.target.getAttribute('id');
    console.log(targetId);
  }

  render() {
    return(
      <div class="container">
        <div class="row">
          <div class="col-md-6 col-md-offset-3">
            <div class="jumbotron text-center">
              {
                this.state.data.map((dynamicData, key) =>
                <div>
                  <a href={"/#/template"} id={dynamicData.id} onClick={this.reply_click}>{dynamicData.name}</a>
                  <a href={"/#/addTeams"}><button type="button" class="btn-lisa">Edit</button></a>
                  <Template name={dynamicData.id}></Template>
                </div>
                )
              }
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default Tournaments;

Template.js:

import React, { Component } from "react";
import Parser from 'html-react-parser';
import Tournaments from "./Tournaments";
import './template.css';
import './index.css';

const tournyAPI = 'http://localhost:8080/api/tournaments';
const teamAPI = 'http://localhost:8080/api/teams'

class template extends Component {

  constructor() {
    super();
    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch(tournyAPI)
    .then((Response) => Response.json())
    .then((findresponse) => {
      this.setState({
        tournydata:findresponse.filter(res => res.id === 18),
      })
    })

Итак, в основном моя цель - использовать targetID из Tournament.js вместо «18» в ComponentDidMount в Template.js

Ответы [ 3 ]

0 голосов
/ 28 апреля 2018

В вашем примере это очень просто, так как вы визуализируете <Template> в цикле, вы можете передать его как параметр

Задача 1

Реактивная цель не в том, чтобы манипулировать таким вот домом var targetId = event.target.getAttribute('id') У вас есть этот идентификатор, почему вы выбираете его из DOM? Вместо этого примите это как param

 <a href={"/#/template"} id={dynamicData.id} onClick={(e) => this.reply_click(e, dynamicData.id)}>{dynamicData.name}</a>

и

reply_click(event, targetId) {

    console.log(targetId);
  }

Никогда не запрашивай DOM в React. Вы получите беспорядок и ошибки из-за несмонтированных элементов и т. Д. React использует JSDom (в памяти), а не Real DOM

Задача 2

Просто передайте это как параметр

и вызов setState внутри reply_click

reply_click(event, targetId) {

    console.log(targetId);
    this.setState({targetID: targetId})
  }
0 голосов
/ 28 апреля 2018

Вы должны сохранить это значение в родительском компоненте state и передать его как реквизит для ребенка.

Когда ваш onClick уволен, вы должны обновить родителей state, поэтому обновленный props будет передан ребенку.

Вот код:

Tournament.js

import React, { Component } from "react";
import Template from './template';

const API = 'http://localhost:8080/api/tournaments';

class Tournaments extends Component {

  constructor() {
    super();
    this.state = {
      data: [],
      targetId: null,
    }
  }

  componentDidMount() {
    fetch(API)
    .then((Response) => Response.json())
    .then((findresponse) => {
      console.log(findresponse)
      this.setState({
        data:findresponse,
      })
    })
  }

  reply_click = id => {
    return () => {
        this.setState({ targetId: id })
    }
  }

  render() {
    return(
      <div class="container">
        <div class="row">
          <div class="col-md-6 col-md-offset-3">
            <div class="jumbotron text-center">
              {
                this.state.data.map((dynamicData, key) =>
                <div>
                  <a href={"/#/template"} onClick={this.reply_click(dynamicData.id)}>{dynamicData.name}</a>
                  <a href={"/#/addTeams"}><button type="button" class="btn-lisa">Edit</button></a>
                  <Template name={dynamicData.id} targetId={this.state.targetId}></Template>
                </div>
                )
              }
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default Tournaments;

Template.js

import React, { Component } from "react";
import Parser from 'html-react-parser';
import Tournaments from "./Tournaments";
import './template.css';
import './index.css';

const tournyAPI = 'http://localhost:8080/api/tournaments';
const teamAPI = 'http://localhost:8080/api/teams'

class template extends Component {

  constructor() {
    super();
    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch(tournyAPI)
    .then((Response) => Response.json())
    .then((findresponse) => {
      this.setState({
        tournydata: findresponse.filter(res => res.id === this.props.targetId),
      })
    })

Но сделайте это, используя componentDidUpdate вместо componentDidMount, если хотите обновлять свой Template компонент после каждого изменения targetId.

Вот так:

Template.js

componentDidUpdate(prevProps) {
    if (prevProps.targetId !== this.props.targetId) {
       fetch(tournyAPI)
       .then((Response) => Response.json())
       .then((findresponse) => {
       this.setState({
          tournydata:findresponse.filter(res => res.id === this.props.targetId),
       })
      })
    }
}

Если вам нужно сделать это сразу во время первого рендеринга, просто добавьте проверку, если targetId не null в вашем Tournament компоненте.

Примерно так:

Tournament.js

render() {
    ...
    {this.state.targetId ? <Template name={dynamicData.id} targetId={this.state.targetId}></Template> : null }
    ...
}
0 голосов
/ 28 апреля 2018

Добавьте targetID к вашему родительскому состоянию и передайте его как ребенка:

reply_click(event) {
  var targetId = event.target.getAttribute('id');
  this.setState({ targetID });
}
<Template targetID={this.state.targetID}

В Template вы можете получить к нему доступ this.props.targetID.

Вам необходимо использовать componentDidUpdate, см. Дочерний компонент React не обновляется при обновлении состояния родительского компонента

...