简体   繁体   English

如何使用从另一个组件传递的输入值重新渲染一个反应组件

[英]How to re-render a react component with an input value passed from another component

Beginner React/JS question -初学者 React/JS 问题 -

In my React app, I have a search bar contained in the 'Navbar' component, and a 'FilmTable' component that displays the results of a fetch request in a table on the homepage.在我的 React 应用程序中,我有一个包含在“Navbar”组件中的搜索栏,以及一个“FilmTable”组件,该组件在主页的表格中显示获取请求的结果。 On the initial page render (componentDidMount), the FilmTable component returns all the films in my DB (http:/url/films).在初始页面呈现 (componentDidMount) 上,FilmTable 组件返回我的数据库 (http:/url/films) 中的所有电影。 I need it to re-render the FilmTable component with a new URL for the fetch request (eg. http:/url/films?title=somefilm), based on the input of the search bar in the navbar component.我需要它根据导航栏组件中搜索栏的输入,使用新的 URL 为获取请求(例如 http:/url/films?title=somefilm)重新呈现 FilmTable 组件。

I'm a bit lost on how to pass the data given in the search bar to the other component and re-render it with the new URL (as derived from the search value).我对如何将搜索栏中给出的数据传递给其他组件并使用新的 URL(从搜索值派生)重新呈现它有点迷茫。

FilmTable.js component: FilmTable.js组件:

import React from "react";
class FilmTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      films: []
    };
  }

  componentDidMount() {
    fetch("http://url/films/")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            films: result.films
          });
        },
        
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

NavBar.js component: NavBar.js组件:

class Navbar extends React.Component {
    render() {
        return (
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <a className="navbar-brand mx-3" href="index.html">Internet Film Database</a>
                <ul className="navbar-nav mr-auto">
                    <li className="nav-item">
                        <a href="#" className="btn btn-dark mx-1" id="insert-button">Insert a new film</a>
                        <a href="#" className="btn btn-dark mx-1" id="update-button">Update film</a>
                        <a href="#" className="btn btn-danger mx-1" id="insert-button">Delete film</a>
                    </li>
                </ul>
                <div className="w-25 ms-auto pr-4 mx-3">
                    <form className="form-inline mx-2 mx-lg-0 input-group">
                        <input className="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"></input>
                        <button className="btn btn-outline-success mx-2 mx-sm-0" type="submit">Search</button>
                    </form>
                </div>
            </nav>)
    }
}

Index.js索引.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <div>
    <Navbar />
    <FilmTable />
  </div>

);

Thanks for reading谢谢阅读

Create a Parent Component: Home.js创建父组件:Home.js

Home.js首页.js

  class Home extends React.Component {
     constructor(props) {
      super(props);
      this.state = {
        films: [],
        searchParam: ""
      };
   }
   render() {
     return (
      <>
        <Navbar searchParam={searchParam}/>
        <FilmTable films={this.state.films}/>
      </>
     )
   }
 }

On submitting searchParams, fetch the data from api and update the films props which will then update the FilmTable Component.在提交 searchParams 时,从 api 获取数据并更新电影道具,这将更新 FilmTable 组件。

You have to lift the state ( React docs ).您必须解除 state( React 文档)。 Since data only flows from parent to child in React, and NavBar and FilmTable are just siblings, you need to wrap them in some parent that stores the search term.由于 React 中数据仅从父级流向子级,而 NavBar 和 FilmTable 只是兄弟姐妹,因此您需要将它们包装在存储搜索词的某个父级中。 You would then pass down the setter function and state value as props to the two child components.然后,您可以将 setter function 和 state 值作为 props 传递给两个子组件。

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      searchTerm: ""
    };
  }

  handleSearchChange(searchString) {
    this.setState({ searchTerm: searchString });
  }

  render() {
    return (
      <div>
        <Navbar handleSearchChange={this.handleSearchChange}/>
        <FilmTable searchTerm={this.searchTerm}/>
      </div>
    );
  }
}

// In NavBar, the onSubmit or onChange triggers will now call
// the function you passed down as props.
<form onSubmit={e => this.props.handleSearchChange(e.target.value)} >
</form>

// In FilmTable:
// Since the NavBar changes the state on the parent, 
// and FilmTable is a child of parent, it will
// re-remount with the passed in searchTerm prop.
fetch(`http://url/films?title=${this.props.searchTerm}`)

It's also convention to use " Controlled Components " in React, so you might want to turn the form into one.在 React 中使用“受控组件”也是一种惯例,因此您可能希望将表单变成一个。 If you do, make sure to use props.searchTerm and props.handleSearchChange instead of adding local state to the NavBar.如果这样做,请确保使用 props.searchTerm 和 props.handleSearchChange 而不是将本地 state 添加到 NavBar。

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

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