反应将 onClick 值从一个 class 传递给另一个

React passing onClick value from one class to another

在 Tournaments.js 中,我有一个锦标赛名称列表,每个名称都有从 API 中获取的唯一 ID。现在,每当我点击其中一个锦标赛名称时,我都会得到它的 ID,但我需要将此 ID 传递给 Template.js,在那里我可以根据点击的锦标赛 ID 获取锦标赛数据。我正在尝试通过将道具从 child 传递到 parent 来做一些事情,但我现在完全迷路了。

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),
      })
    })

所以基本上我的目标是使用 Tournament.js 中的 targetID 代替 Template.js

中 ComponentDidMount 中的“18”

targetID 添加到您的父状态并作为 prop 传递给子状态:

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

Template 中,您可以使用 this.props.targetID 访问它。

不过您需要使用 componentDidUpdate,请参阅

在你的例子中这很容易,因为你在循环中渲染 <Template> 你可以将它作为参数传递

问题 1

React 的目的不是像这样操纵 dom var targetId = event.target.getAttribute('id') 你有这个 id,为什么要从 DOM 中获取它?而不是接受它作为参数

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

reply_click(event, targetId) {

    console.log(targetId);
  }

永远不要在 React 中查询 DOM。由于未安装的元素等,您会遇到混乱和错误。React 使用 JSDom(在内存中)而不是 Real DOM

问题 2

作为参数传递即可

并在 reply_click

中调用 setState
reply_click(event, targetId) {

    console.log(targetId);
    this.setState({targetID: targetId})
  }

您应该将此值保留在 parent 的组件 state 中,并将其作为 prop 传递给 child。

当你的 onClick 被解雇时你应该更新 parents state 所以更新的 props 将被传递给 child。

代码如下:

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),
      })
    })

但是,如果您想在每次更改 targetId 后继续更新 Template 组件,请使用 componentDidUpdate 而不是 componentDidMount

像这样:

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),
       })
      })
    }
}

如果您需要在第一次渲染期间立即执行此操作,只需在 Tournament 组件中添加检查 targetId 是否不是 null

像这样:

Tournament.js

render() {
    ...
    {this.state.targetId ? <Template name={dynamicData.id} targetId={this.state.targetId}></Template> : null }
    ...
}