简体   繁体   English

在React中将状态从子级传递到父级; 孩子有单独的状态

[英]Passing state from child to parent in React; child has separate state

I have three components, from outermost to innermost: App => Welcome => SearchBar . 我有三个组成部分,从最外层到最内层: App => Welcome => SearchBar There's a state defined in App and SearchBar , but what I want is to get the user-inputted data in SearchBar and display that in a "Results" page. AppSearchBar定义了一个状态,但是我想要的是在SearchBar中获取用户输入的数据并将其显示在“结果”页面中。 As such, I'm trying to update the state in SearchBar and have that simultaneously update the state in App , so that I can pass that data on to another component that's a child of App (eg Results ). 因此,我正在尝试更新SearchBar的状态,并同时更新App的状态,以便可以将数据传递到App的子组件中(例如Results )。 I have the following code, but it's only updating the state in SearchBar and not that in App . 我有以下代码,但它仅更新SearchBar的状态,而不更新App

(I've looked at some examples where the child (in this case SearchBar ) doesn't have its own state, but in this case I think it's necessary since I'm tracking user input. I may be wrong though.) (我看过一些例子,其中孩子(在这种情况下为SearchBar )没有自己的状态,但是在这种情况下,我认为这是必要的,因为我正在跟踪用户输入。但是我可能是错的。)

// App.js
export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "" };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({
      value: event.target.value
    });
  }

  render() {
    return (
      <Router>
        <div className="AppContainer">
          <Route
            exact
            path="/"
            render={props => <SearchBar handleSubmit={this.handleSubmit} />}
          />
...

// Welcome.js
export default class Welcome extends React.Component {
  render() {
    return (
      <div>
        <SearchBar handleSubmit={this.props.handleSubmit} />
      </div>
...

// SearchBar.js
export default class SearchBar extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "" };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    event.preventDefault();
    this.setState({ value: event.target.value });
  }

  render() {
    return (
      <form onSubmit={this.props.handleSubmit}>
        <input
          type="text"
          placeholder="Search..."
          onChange={this.handleChange}
          value={this.state.value}
        />
        <input type="submit" />
      </form>
    );
  }
}

Then again, I'm quite new to React so this might not be a pattern that you're supposed to use. 再说一遍,我对React还是很陌生,所以这可能不是您应该使用的模式。 In any case, I would appreciate advice on how to best solve this. 无论如何,我将对如何最好地解决此问题提出建议。

Since you've already defined a handleSubmit() event-handler in App.js and passed it all the way down to your SearchBar.js component. 既然你已经定义的handleSubmit()事件处理程序App.js ,并通过它一路下跌到你的SearchBar.js组件。 You can extrapolate the data you need by giving the input tag in your SearchBar a name prop. 您可以通过在SearchBar中为输入标签指定名称道具来推断所需的数据。

class Searchbar extends React.Component {
  state = {
    value: ""
  };

  handleOnChange = e => {
    this.setState({
      value: e.target.value
    });
  };

  render() {
    return (
      <form onSubmit={this.props.handleSubmit}>
        <input
          onChange={this.handleOnChange}
          value={this.state.value}
          name="search"
        />
      </form>
    );
  }
}

Then in App.js handleSubmit handler, target that name prop to get the value in the input. 然后在App.js handleSubmit处理程序中,以该name prop为目标,以获取输入中的value

  handleSubmit = e => {
    e.preventDefault();
    this.setState({
       value: e.target.search.value
    })
  };

This will likely have the least amount of re-renders. 这可能会使重新渲染的次数最少。

Edit: 编辑:

Yes we can totally display a new component upon submitting the form. 是的,提交表格后,我们可以完全显示一个新组件。 We just need the help of a second state-value like displayResults or displayComponent then by using a simple if-check, we'll just toggle what components to show. 我们只需要第二个状态值(例如displayResultsdisplayComponent的帮助,然后通过使用简单的if-check,就可以切换要显示的组件。 See working example: Code Demo 请参见工作示例: 代码演示

In SearchBar component you should pass state value directly to handleSubmit function as, SearchBar组件中,您应该将state值直接传递给handleSubmit函数,例如,

<form onSubmit={(e)=>{e.preventDefault(); this.props.handleSubmit(this.state.value)}}>

In App component your handleSubmit function should be, App组件中, handleSubmit函数应为:

handleSubmit(inputValue) {
    this.setState({
      value: inputValue
    });
}

Demo 演示版

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

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