首页 > 解决方案 > 通过单击按钮更新元素

问题描述

非常新的反应,并试图找出处理通过按钮单击更新自定义小部件的最佳方法。到目前为止,我有 3 个小部件 - 一个文本框、按钮和一个 twitter 嵌入式提要。我想基本上更新 twitter 提要以在单击按钮后使用文本框中的输入重新呈现:

constructor(props){
      super(props)
      console.debug(props)
      this.state = {
        searchTerm: "test",
        selectedOption: null
      }
      this.onTextChange = this.onTextChange.bind(this);
      this.appChange = this.appChange.bind(this);
      this.searchClicked = this.searchClicked.bind(this);
    }

    onTextChange(e){
      this.setState({
        searchTerm: e.target.value
      });
    };

    appChange = selectedOption => {
      this.setState({ selectedOption });
      console.log('Option: ', selectedOption);
    }

    searchClicked(e){
      this.setState({
        searchTerm: e.target.value
      })

render() {
        const { searchTerm } = this.state;


        return(
          <div>
            <div className="hashtag">
                <input name="search" type="text" className="textBox" placeholder={this.state.searchTerm} onInput={this.onTextChange}/>
                <br />
                <button id="btnSearch" className="searchBtn" onClick={this.searchClicked}>Search</button>
                <TwitterTimelineEmbed
                  sourceType="profile"
                  screenName={this.state.searchTerm}
                  options={{height:400, width: 400}}
                />
            </div>
          </div>
        );
    }
}

我尝试过使用 componentDidUpate(),但没有成功传递以前的道具/状态。

标签: reactjs

解决方案


问题是,当您单击提交时,您将覆盖状态e.target.value- 这没什么,因为它e.target是实际的提交按钮,而不是输入字段。

您不需要setStateinside of,searchClicked因为状态会在每次按键时更新(in onTextChange)。

我也删除了appChange,因为您在此代码段中不需要它。

该解决方案要求您添加一个key<TwitterTimelineEmbed />以便在您想要更新用户名时销毁旧实例。

Twitter 组件不允许您在状态更改时更新组件,这很好,否则您很容易在每次重新渲染时意外调用 Twitter API,这可能(很可能)不是您想要的。

import React, { PureComponent } from "react";
import { TwitterTimelineEmbed } from "react-twitter-embed";

class Search extends PureComponent {
  constructor(props) {
    super(props);

    this.timelineId = 0; // initialize key

    this.state = {
      searchTerm: "TwitterEng"
    };

    this.onTextChange = this.onTextChange.bind(this);
    this.searchClicked = this.searchClicked.bind(this);
  }

  onTextChange(e) {
    this.setState({
      searchTerm: e.target.value
    });
  }

  searchClicked(e) {
    // notice we removed the setState

    ++this.timelineId; // this is the key for the timelinefeed

    this.forceUpdate(); // you need to force update here if you want to update on search
  }

  render() {
    const { searchTerm } = this.state;

    return (
      <div>
        <div className="hashtag">
          <input
            name="search"
            type="text"
            className="textBox"
            placeholder={searchTerm}
            onInput={this.onTextChange}
          />
          <br />
          <button
            id="btnSearch"
            className="searchBtn"
            onClick={this.searchClicked}
          >
            Search
          </button>
          <TwitterTimelineEmbed
            key={this.timelineId}
            sourceType="profile"
            screenName={searchTerm}
            options={{ height: 400, width: 400 }}
          />
        </div>
      </div>
    );
  }
}

export default Search;

推荐阅读