Search code examples
javascriptreactjscomponentsstateonchange

Getting the current state value of an exported component


I have built an Autocomplete component for my React app and exported it into another component using this tutorial. Everything is working for the autocorrect but I have a separate button that needs to grab the state value of the autocomplete the user inputs and insert it as a parameter into an API call during the forms onSubmit event.

<div className="sidebar" style={{
            borderLeft: "1px solid gray"
        }}>
            <h2 style={{ textAlign: "center" }}> Filter</h2>
            <form onSubmit={(e) => { e.preventDefault(); callSearchAPI({//Autocomplete value}); }}>
                <label style={{}}>Name</label> <br />
                <input
                    placeholder="Type name"
                    style={{ textAlign: "center", marginRight: "10px", height: "25px" }}
                    value={interest}
                    onChange={HandleChange}></input>
                <Autocomplete suggestions={namesData} />
                <button className="btn btn-primary" > Search</button>
                <br />
                <div>{namesData}</div>
            </form>
            <p>{namesData}</p>
        </div>

The Autocomplete component has an onChange and onClick event handler/listener that updates the component state whenever a new value is entered in the textbox or selected frrom the autocomplete dropdown. All I need to do is grab that current value in the other component and plug it into <form onSubmit={(e) => { e.preventDefault(); callSearchAPI({//Autocomplete value}); }}> (if this was vanilla javascript I could simply add an id and use => document.getElementById("Autocomplete").value). How can I do this in React? Can I create another onChange handler in second component or is there a simpler solution?

class Autocomplete extends Component {
    constructor(props) {
        super(props);
        this.state = {
            activeSuggestion: 0,
            filteredSuggestions: [],
            showSuggestions: false,
            userInput: ""
        };
    }

    onChange = e => {
        const { suggestions } = this.props;
        const userInput = e.currentTarget.value;

        const filteredSuggestions = suggestions.filter(
            suggestion =>
                suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
        );

        this.setState({
            activeSuggestion: 0,
            filteredSuggestions,
            showSuggestions: true,
            userInput: e.currentTarget.value
        });
    };

Solution

  • From the parent component you can use a React ref to access the state of the child class component.

    const autoCompleteRef = useRef(); // <-- (1) create a ref
    
    ...
    
    <form
      onSubmit={(e) => {
        e.preventDefault();
    
        // access the state
        const { state } = autoCompleteRef.current; // <-- (3) access ref current value
        console.log(state.userInput);
    
        callSearchAPI({//Autocomplete value});
      }}
    >
      <label>Name</label>
      <br />
      <input
        placeholder="Type name"
        style={{ textAlign: "center", marginRight: "10px", height: "25px" }}
        value={interest}
        onChange={HandleChange}
      />
      <Autocomplete
        ref={autoCompleteRef} // <-- (2) attach the ref
        suggestions={namesData}
      />
      <button className="btn btn-primary">Search</button>
      <br />
      <div>{namesData}</div>
    </form>