btholt / complete-intro-to-react

A Complete Intro to React, as Given for Frontend Masters
https://frontendmasters.com/learn/react/
MIT License
1.06k stars 929 forks source link

How to share a state of Landing component into App so that I can distinguish a searchTerm into Search component? #70

Open szymonhernik opened 7 years ago

szymonhernik commented 7 years ago

Hi, Can anyone tell me how can I share a state of the Landing component into the App so that I can distinguish a searchTerm in the Search component? Basically, I'd like to make the Landing component working.

This is sth that Brian talks about in the React Wrapper in the chapter 'Data in React' (FEM course). https://frontendmasters.com/courses/react/wrapper-and-q-a/

I've been trying to refactor Landing.jsx. Now it looks like this:

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class Landing extends Component {
  state = {
    beforeSearchTerm: ''
  };

  handleSearchTermChange = (event: SyntheticKeyboardEvent & { target: HTMLInputElement }) => {
    this.setState({ beforeSearchTerm: event.target.value });
  };

  render() {
    return (
      <div className="landing">
        <h1>svideo</h1>
        <input
          type="text"
          placeholder="Search"
          onChange={this.handleSearchTermChange}
          value={this.state.beforeSearchTerm}
        />
        <Link to="/search"> Search</Link>
        <Link to="/search">or Browse All</Link>
      </div>
    );
  }
}

export default Landing;

Now I want this beforeSearchTerm state send into Search component so I can distinguish searchTerm, maybe sth like this-> if I pass sth in Landing component (beforeSearchTerm) then let Search state be beforeSearchTerm, if I don't pass any value then let Search state be empty string:

class Search extends Component {
  state = {
    searchTerm: beforeSearchTerm ? {`${beforeSearchTerm}`} : ''
  };
Strikeh commented 7 years ago

I would like to know this as well !

jpedroribeiro commented 7 years ago

I've done something similar to yours, except that I wrapped the search input with a <form> and the Search link made into a submit button:

// Landing.jsx
<form onSubmit={this.goToSearch}>
<input type="text" placeholder="Search" onChange={this.handleKeyboardUpdate} />
<input type="submit" />

So when clicking on Search, I would take you to the search page with a search term on the URL, like this:

// Landing.jsx
goToSearch = event => {
event.preventDefault();
this.props.history.push(`/search/${this.state.searchTerm}`);

};

I also had to add a new route to App so it would cater for that pattern:

// App.jsx
<Route
      path="/search/:query"
      component={props => <Search searchQuery={props.match.params.query} shows={preload.shows} {...props} />}
 />

And finally, I made Search state to pick up searchQuery coming from the App:

// Search.jsx state = { searchTerm: this.props.searchQuery };

Might not be the most optimal answer but that's what I got so far ;-)