React将onClick值从一个类传递到另一个类

时间:2018-04-28 14:31:07

标签: reactjs api react-router react-props

在Tournaments.js中,我有一个锦标赛名称列表,每个名称都有唯一的ID,这些ID是从API获取的。现在每当我点击其中一个锦标赛名称时,我都会得到它的ID,但我需要将此ID传递给Template.js,我可以根据点击的锦标赛ID获取锦标赛数据。我正在尝试将道具从孩子传给父母,但我现在完全迷失了。

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'

3 个答案:

答案 0 :(得分:1)

您应该将此值保留在父组件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代替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 }
    ...
}

答案 1 :(得分:0)

targetID添加到您的父状态,并将其作为prop传递给child:

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

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

您需要使用componentDidUpdate,请参阅React Child component don't update when parent component's state update

答案 2 :(得分:0)

在您的示例中,当您在循环中渲染<Template>时,您可以将其作为参数传递

,这非常简单

问题1

反应的目的不是像这样操纵dom var targetId = event.target.getAttribute('id')你有这个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);
  }

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

问题2

将其作为参数传递

并在reply_click

中调用setState
reply_click(event, targetId) {

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