简体   繁体   English

从父组件中访问子组件引用

[英]Accessing child component refs from within a parent component

I'm creating a simple React app that loads movie data from the OMDb API based on a search -- so far, so good. 我正在创建一个简单的React应用,该应用基于搜索从OMDb API加载电影数据-到目前为止,一切都很好。

However, I refactored the app and added the data fetching logic in a parent container component . 但是,我重构了应用程序,并在父容器组件中添加了数据获取逻辑。 Now I'm having trouble accessing the search field's value via refs from within the container component . 现在,我很难通过容器组件内部的refs访问搜索字段的值。

My component hierarchy looks like this (each component in its own file): 我的组件层次结构如下所示(每个组件在其自己的文件中):

example

The state and props seem to be fine and are being passed correctly. stateprops似乎很好,可以正确传递。 This is the JS for the main component -- I'm using axios to fetch data from the API: 这是主要组件的JS-我正在使用axios从API中获取数据:

class MovieSearchContainer extends Component {

  constructor(props) {
    super(props);
    this.state = {
      Search: [] 
    };
    this._performSearch = this._performSearch.bind(this);
  }

  _performSearch() {
    var _this = this;

    let query = I WANT TO ACCESS THE SEARCH FIELD VALUE HERE, maybe?;

    this.serverRequest = 
      axios
        .get(`http://www.omdbapi.com/?s=${query}&r=json`)
        .then(function(result) {    
          _this.setState({
            Search: result.data.Search
          });
        }) 

    .catch((error) => {
      console.log('Error fetching and parsing data', error);
    });
  }

  render() {
    return(
      <Application query={this.state.Search}
                   onSearch={this._performSearch} />
    );
  }
}

ReactDOM.render(<MovieSearchContainer />, document.getElementById('app'));

Then, further nested, I have a <SearchForm /> component with the following JS: 然后,进一步嵌套,我有了一个带有以下JS的<SearchForm />组件:

class SearchForm extends Component {

  constructor() {
    super();
    this.state={
      searchText: ''
    };
  }

  _onSearchChange(e) {
    const searchText = e.target.value;
    this.setState({ searchText: searchText });
  }

  _handleSubmit(e) {
    if (e) e.preventDefault();
    this.props.onSearch(this.state.Search);
  }

  render() {
    return (
      <form className="search-form" onSubmit={this._handleSubmit.bind(this)} >
        <label className="is-hidden" for="search">...</label>
        <input type="search" 
               onChange={this._onSearchChange.bind(this)}
               name="search" 
               ref="query"
               placeholder="Search a Title..." />
        <button type="submit" id="submit" className="search-button">...</button>
      </form>      
    );
  }
}

The big question is: How can I access the ref (or value) of the input inside <SearchForm /> , from within <MovieSearchContainer /> , so that I can pass that value into the API call? 最大的问题是:如何从<MovieSearchContainer />访问<SearchForm />内的inputref (或值),以便可以将该值传递给API调用?

 // MovieSearchContainer

  _performSearch() {
    var _this = this;

    let query = I WANT TO ACCESS THE SEARCH FIELD VALUE HERE, maybe?;

    this.serverRequest = 
      axios
        .get(`http://www.omdbapi.com/?s=${query}&r=json`)
        .then(function(result) {    
          _this.setState({
            Search: result.data.Search
          });
        }) 
  }

Should I place this logic elsewhere? 我应该把这个逻辑放在其他地方吗?

I've tried methods like ReactDOM.findDOMNode(this.refs.query).value and a few others, but no luck. 我已经尝试过像ReactDOM.findDOMNode(this.refs.query).value和其他一些方法,但是没有运气。

Please let me know if you need me to provide more code. 如果您需要我提供更多代码,请告诉我。 :) :)

UPDATE: I was passing the same ref value to each child component, including the input I was trying to target. 更新:我正在将相同的ref值传递给每个子组件,包括我尝试定位的input For example: 例如:

// component hierarchy
<Application />
  <Header onSearch={this._performSearch} ref="query" />
    <SearchForm onSearch={this.props.onSearch} ref="query" />
      <input ... ref="query" />

I was calling this.refs.query.value in the container component , which only targets the outermost element of the rendered child component. 我在容器组件中调用this.refs.query.value ,它仅针对呈现的子组件的最外层元素。

So instead, I passed a different ref value for each component, including the input node: 因此,我为每个组件(包括input节点)传递了一个不同的ref值:

<Header onSearch={this._performSearch} ref="header" />
  <SearchForm onSearch={this.props.onSearch} ref="searchform" />
    <input ... ref="query" />

Then, in my _performSearch() method, I targeted the input value like this: 然后,在我的_performSearch()方法中,我将input值作为目标:

_performSearch() {
  var query = this.refs.header.refs.searchform.refs.query.value;
  this.serverRequest = 
    axios
      .get(`http://www.omdbapi.com/?s=${query}&r=json`)
      ...
}

It works great, but seems a bit code smelly. 它很好用,但似乎有点代码臭味。 Any cleaner suggestions? 还有更清洁的建议吗? :) :)

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

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