简体   繁体   English

React.js使用共享的onClick函数定位单个元素

[英]React.js targeting a single element with a shared onClick function

I am new to both coding as well as React.js, so any assistance in learning what I am doing incorrectly is greatly appreciated! 我对编码和React.js都是新手,因此非常感谢您对我做得不正确的学习有所帮助! I am creating multiple cards on a page with riddles where the answer is hidden via css. 我在带有谜题的页面上创建了多张卡片,答案是通过CSS隐藏的。 I am using an onClick function ("toggleAnswer") to toggle the state of each answer to change the className so that the answer will either be visible or hidden. 我正在使用onClick函数(“ toggleAnswer”)来切换每个答案的状态以更改className,以便答案将可见或隐藏。 Currently, the onClick event is changing the state for all the answers. 当前,onClick事件正在更改所有答案的状态。 I realize this is because my code is not targeting a particular element, but I am unsure how this can be done. 我意识到这是因为我的代码没有针对特定元素,但是我不确定如何做到这一点。 How can this be achieved? 如何做到这一点? My code is currently like this: 我的代码当前是这样的:

// RiddlesPage where toggleAnswer function is defined
class RiddlesPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            questionData: [],
            isHidden: true
        };
        this.getPageData = this.getPageData.bind(this);
        this.toggleAnswer = this.toggleAnswer.bind(this);
    }
    getPageData() {
        console.log("we hit getPageData function starting --");
        helpers.getRiddlesPage().then(data => {
            console.log("this is the result", data);
            this.setState({
                questionData: data[0].questionData,
            });
        });
    }
    toggleAnswer(e) {
        this.setState({ isHidden: !this.state.isHidden });
    }
    componentWillMount() {
        this.getPageData();
    }
    render() {
        const answerClass = this.state.isHidden ? "answer-hide" : "answer";
        return (
            <div>
                <Riddles>
                    {this.state.questionData.map((data, index) => {
                        return (
                            <RiddlesItem
                                key={index}
                                id={index}
                                question={data.question}
                                answer={data.answer}
                                button={data.buttonURL}
                                answerClass={answerClass}
                                onClick={this.toggleAnswer}
                            />
                        );
                    })}
                </Riddles>
            </div>
        );
    }
}
export default RiddlesPage;

// Riddles Component
import React from "react";
import "./riddles.css";
const Riddles = props => (
    <div id="riddles-row">
        <div className="container">
            <div className="row">
                <div className="col-12">
                    <div>{props.children}</div>
                </div>
            </div>
        </div>
    </div>
);
export default Riddles;

// RiddlesItem Component where onClick function is set as a prop
import React from "react";
import "./riddles.css";
const RiddlesItem = props => (
  <div>
      <div className="card-body">
            <p id="question">{props.question}</p>    
            <img
              className="img-fluid"
              id={props.id}
              src={props.button}
              onClick={props.onClick}
              alt="answer button"
            />     
        <p className={props.answerClass}> {props.answer} </p>
      </div>
  </div>
);
export default RiddlesItem;

You'd have to keep track of each answer that has been shown in state (in an array or something). 您必须跟踪状态(以数组或其他形式)显示的每个答案。

First 第一

Send the index of the answer up in the onclick function. 在onclick函数中向上发送答案的索引。 In that function, check if it exists in the "shownAnswers" array and either add or remove it. 在该函数中,检查它是否存在于“ shownAnswers”数组中,然后添加或删除它。

onClick={e => props.onClick(e, props.id)}

and

toggleAnswer(e, index) {
    if (this.state.shownAnswers.indexOf(index) > -1) {
        this.setState({
            shownAnswers: this.state.shownAnswers.filter(val => val !== index)
        });
    } else {
        this.setState({
            shownAnswers: this.state.shownAnswers.concat(index)
        });
    }
}

Then 然后

When you're passing the class name down to the child component, check if its index is in the "shownAnswers" array to decide which class name to pass. 在将类名传递给子组件时,请检查其索引是否在“ shownAnswers”数组中,以确定要传递的类名。

answerClass={this.state.shownAnswers.indexOf(index) > -1 ? "answer" : "answer-hide"}

Building off your example, it could look something like this (untested): 以您的示例为基础,它可能看起来像这样(未经测试):

// RiddlesPage where toggleAnswer function is defined
class RiddlesPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            questionData: [],
            shownAnswers: []
        };
        this.getPageData = this.getPageData.bind(this);
        this.toggleAnswer = this.toggleAnswer.bind(this);
    }
    getPageData() {
        console.log("we hit getPageData function starting --");
        helpers.getRiddlesPage().then(data => {
            console.log("this is the result", data);
            this.setState({
                questionData: data[0].questionData,
            });
        });
    }
    toggleAnswer(e, index) {
        if (this.state.shownAnswers.indexOf(index) > -1) {
            this.setState({ shownAnswers: this.state.shownAnswers.filter(val => val !== index) });
        } else {
            this.setState({ shownAnswers: this.state.shownAnswers.concat(index) });
        }
    }
    componentWillMount() {
        this.getPageData();
    }
    render() {
        return (
            <div>
                <Riddles>
                    {this.state.questionData.map((data, index) => {
                        return (
                            <RiddlesItem
                                key={index}
                                id={index}
                                question={data.question}
                                answer={data.answer}
                                button={data.buttonURL}
                                answerClass={this.state.shownAnswers.indexOf(index) > -1 ? "answer" : "answer-hide"}
                                onClick={this.toggleAnswer}
                            />
                        );
                    })}
                </Riddles>
            </div>
        );
    }
}
export default RiddlesPage;

// Riddles Component
import React from "react";
import "./riddles.css";
const Riddles = props => (
    <div id="riddles-row">
        <div className="container">
            <div className="row">
                <div className="col-12">
                    <div>{props.children}</div>
                </div>
            </div>
        </div>
    </div>
);
export default Riddles;

// RiddlesItem Component where onClick function is set as a prop
import React from "react";
import "./riddles.css";
const RiddlesItem = props => (
  <div>
      <div className="card-body">
            <p id="question">{props.question}</p>    
            <img
              className="img-fluid"
              id={props.id}
              src={props.button}
              onClick={e => props.onClick(e, props.id)}
              alt="answer button"
            />     
        <p className={props.answerClass}> {props.answer} </p>
      </div>
  </div>
);
export default RiddlesItem;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM