简体   繁体   English

如何处理条件组件中的onClick事件

[英]How to handle onClick event inside a conditional component

I'm trying to add the onClick event on the data I selected from the AsyncTypeahead. 我正在尝试在从AsyncTypeahead选择的数据上添加onClick事件。 I'm passing the callback function to the Problem that renders only if I've selected an item. 我将回调函数传递给仅在选择项目后才呈现的问题。 But after selecting an item it directly calling the callback function that I passed to Problem component 但是选择一个项目后,它直接调用我传递给问题组件的回调函数

This is main Component 这是主要成分

constructor(props) {
    super(props);

    this.state = {
        plateform: '',
        selected: [],
        isLoading: false,
        options: []
    };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.saveTodo = this.saveTodo.bind(this);
}

async handleInputChange(event) {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    await this.setState({
      [name]: value
    });
}

saveTodo(problemID) {
    axios.post(`${API}/todos`,
    {
        problemID: problemID
    },
    {
        headers: {
            Accept: "application/json",
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + this.props.auth.token
        }
    })
    .then(() => alert("Problem saved to todo list"))
    .catch((err) => {
        if (err.response) {
            alert(err.response.data);
        }
        else {
            alert("Sorry! A server error occurred. Try to save this problem later!");
        }
    });
}


render() {

    return (
        <>
            <TrainLayout auth={this.props.auth} deauthenticate={this.props.deauthenticate} title={title} description={description} >
                <div className="container">
                    <div className="row justify-content-center">
                        <div className="offset-md-3 col-md-7 offset-2">
                            <br />
                            <div className="form-group row">
                                <label htmlFor="oj" className="col-4 col-form-label col-form-label-sm">Online Judge</label>
                                <div className="col-8 col-md-5">
                                    <select id="oj" type="select" className="form-control form-control-sm" name="plateform" onChange={this.handleInputChange} value={this.state.plateform}>
                                        <option value="all">All Online Judges</option>
                                        <option value="xxx">XXX</option>
                                        <option value="yyy">YYY</option>
                                        <option value="zzz">ZZZ</option>
                                    </select>
                                </div>
                            </div>
                            <div className="form-group row">
                                <label htmlFor="pname" className="col-4 col-form-label col-form-label-sm">Problem Name</label>
                                <div className="col-8 col-md-5">
                                    <AsyncTypeahead
                                        isLoading={this.state.isLoading}
                                        allowNew={false}
                                        multiple={false}
                                        id="pname"
                                        labelKey={option => `${option.name} (${option.plateform})`}
                                        minLength={2}
                                        onChange={selected => this.setState({ selected })}
                                        placeholder="Search for a problem"
                                        onSearch={query => {
                                            this.setState({isLoading: true});
                                            axios.get(`${API}/problems/${query}`,
                                            {
                                                params: {
                                                    plateform: this.state.plateform
                                                },
                                                headers: {
                                                    Accept: "application/json",
                                                    'Content-Type': 'application/json',
                                                    'Authorization': 'Bearer ' + this.props.auth.token
                                                }
                                            })
                                            .then((response) => { /* eslint-disable-line camelcase */
                                                const options = response.data.map((problem) => ({
                                                    _id: problem._id,
                                                    problemID: problem.problemID,
                                                    name: problem.name,
                                                    plateform: problem.plateform,
                                                    link: problem.link,
                                                    difficulty: problem.difficulty
                                                }));
                                                console.log("DATA: ", options);
                                                this.setState({
                                                    isLoading: false,
                                                    options: options,
                                                });
                                            });
                                        }}
                                        options={this.state.options} />
                                </div>
                            </div>

                        </div>
                    </div>
                </div>
                <br /><br />
                <div className="container">
                    <div className="row justify-content-center">
                        {!!this.state.selected &&
                        (
                        <Problem saveTodo={this.saveTodo} problem={this.state.selected[0]} />)
                        }
                    </div>
                </div>
            </TrainLayout>
        </>
    );
}

I expect the Onclick event to be called when I click on the font-awesome icon but it fires when I select an item from AsyncTypeahead 我希望当我单击超赞字体图标时会调用Onclick事件,但是当我从AsyncTypeahead中选择一个项目时会触发该事件

    const Problem = ({problem, saveTodo}) => {
if (!problem) {
    return (
        <></>
    );
}
return (
    <>
        <table className="table table-sm table-bordered table-striped table-responsive-sm table-hover">
            <thead>
                <tr className="text-center">
                    <th>Name</th>
                    <th>Online Judge</th>
                    <th>Difficulty</th>
                    <th>Add Todo</th>
                    <th>Solve</th>
                </tr>
            </thead>
            <tbody>
                <tr className="text-center">
                    <td> {problem.name} </td>
                    <td> {problem.plateform} </td>
                    <td> {problem.difficulty} </td>
                    <td> <a onClick={saveTodo(problem.problemID)}><FontAwesomeIcon icon="save" /></a> </td>
                    <td> <a href={`${problem.link}`} target="_blank"> Solve </a> </td>
                </tr>
            </tbody>
        </table>
        <br />
        <div className="row justify-content-center">
            <p>Note: Difficulty is not 100% accurate</p>
        </div>
    </>
);}

You should be passing a function as the event handler. 您应该传递一个函数作为事件处理程序。 In your example you are calling the function immediately. 在您的示例中,您将立即调用该函数。 Try the following. 请尝试以下方法。

<td> <a onClick={() => saveTodo(problem.problemID)}><FontAwesomeIcon icon="save" /></a> </td>

See Handling Events - React for more info. 有关更多信息,请参见处理事件-React

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

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