简体   繁体   中英

How to pass props from child component to parent component to another child component in ReactJS?

I'm currently creating a search bar where App is the parent and Header , Home are the children. I'm trying to pass the input from Header to Home via App but it seems that when I try to load in {this.state.searchValue} it does nothing.

I'm lost of where I am wrong in my code. I'm also using Route to route the props from Header to Home .

Here is my code:

Header.js (Child 1)

class Header extends Component {
  constructor(props) {
    super(props);
    this.state = {
      search: "",
    };
  }

  onChange = (event) => {
    this.setState({ search: event.target.value });
  };

  submitSearch = (event) => {
    event.preventDefault();
    console.log(this.state.search);
    this.props.passSearchData(this.state.search);
  };

  render() {
    return (
      <React.Fragment>
        <nav className="navbar navbar-expand-lg navbar-light bg-light">
          <form className="form-inline">
                <input
                  className="form-control mr-sm-2"
                  type="text"
                  placeholder="Search"
                  onChange={this.onChange}
                />
                <button
                  className="btn btn-danger"
                  type="submit"
                  onClick={this.submitSearch}
                >
                  Search
                </button>
              </form>
        </nav>
      </React.Fragment>
    );
  }
}

export default Header;

App.js (Parent)

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

  handleSearchData = (search) => {
    this.setState({ searchValue: search });
  };

  componentDidMount() {
    this.props.getItems();
  }

  render() {
    return (
      <div className="App">
        <Router>
          <Header passSearchData={this.handleSearchData} />
          <Route
            exact
            path="/"
            render={(props) => (
              <Home {...props} searchValue={this.state.searchValue} />
            )}
          />
        </Router>
        <Footer />
      </div>
    );
  }
}

Home.js

class Catalog extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
render() {
return (
      <div>
        <p>{this.props.searchValue}</p>
      </div>
    );
  }
}

I think using react context better for this problem, because passing state between routes quite painful

First u declare your own Provider to act as intermediary between components. The context will save all the application state. and to consume at your components, simply use useContext and pass the Context u want to use, at this useCase, i call it AppContext . by using the same context, your components get the same state and trigger update immediately

The solution i provide is using functional component. If u are using class Component, just simply create a functional component, then pass the context to the class component

 import React, { useContext, useState } from 'react' const AppContext = React.createContext({}) const AppProvider = props => { const [currentState, setCurrentState] = useState(null) const handleState = value => { setCurrentState(value) } const contextValue = { handleState, currentState } return ( <AppContext.Provider value={contextValue}> {props.children} </AppContext.Provider> ) } const Child1 = props => { const { handleState } = useContext(AppContext) const handleClick = e => { handleState(e.target.values) } return ( <button onClick={handleClick}>Change State</button> ) } const Child2 = props => { const { currentState } = useContext(AppContext) return ( <h1>{currentState}</h1> ) } const Parent = props => { return ( <Router> <AppProvider> <Route component={Child1} /> <Route component={Child2} /> </AppProvider> </Router> ) }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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