0

I've been trying to retrieve a value from the child component in react for an app I am putting together. I think I am making a very simple error here. I originally asked a related question here:

React read value of button clicked

Right now my code looks like this:

App.js

import React, { Component } from 'react';
import { Form, Button, ListGroup } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import Match from './Match'

const my_data = require('./data/test.json')

class App extends Component {

  state = {
    links: [],
    selectedLink:null,
    userLocation: {},
    searchInput: "",
    showMatches: false,
    matches: [],
    searchLink:[]
}

componentDidMount() {
    fetch('https://data.cityofnewyork.us/resource/s4kf-3yrf.json')
        .then(res=> res.json())
        .then(res=> 
            //console.log(json)
            this.setState({links:res})
        );
}

handleInputChange = (event) => {
    event.preventDefault()
    this.setState({searchInput: event.target.value })
    console.log(event.target.value)
}

handleSubmit = (event) => {
    event.preventDefault()
    this.displayMatches();
}

findMatches = (wordToMatch, my_obj) => {
    return my_obj.filter(place => {
        // here we need to figure out the matches
        const regex = new RegExp(wordToMatch, 'gi');
        //console.log(place.street_address.match(regex))
        return place.street_address.match(regex)
    });
}

displayMatches =() => {
    const matchArray = this.findMatches(this.state.searchInput, this.state.links);
    const newStateMatches = matchArray.map(place => {
        console.log(place.street_address);
        return place   
    });
    this.setState({matches:newStateMatches})
    this.setState({showMatches:true})
}

alertClicked =(event) => {
  event.preventDefault()
  //alert('you clicked an item in the group')
  const data = event.target.value
  console.log('clicked this data:', data)
  this.setState({searchLink: event.target.value})
  console.log(this.state.searchLink)
}

render() {
    return (
        <div>
            <input 
                placeholder="Search for a Link Near you..." 
                onChange = {this.handleInputChange} 
                value = {this.state.searchInput}
            />
            <Button onClick={this.handleSubmit}>
                Search
            </Button>
            <ListGroup defaultActiveKey="#link1">
              {
                this.state.matches.map(match => {
                  return <Match 
                            address={match.street_address} 
                            alertClicked={this.alertClicked}
                            value = {this.state.searchLink}/>
                })
              }
            </ListGroup>

        </div>
    );
}
}

export default App;

Match.js

import React from 'react';
import { ListGroup } from 'react-bootstrap';

const match = ( props ) => {

    return (
        <ListGroup.Item 
            className="Matches" 
            action onClick={props.alertClicked}
            value = {props.value}>
              <p>{`${props.address}`}</p>
        </ListGroup.Item>

    )
};

export default match;

I am trying to access the value of the ListGroup Item when I click on it with this:

alertClicked =(event) => {
  event.preventDefault()
  //alert('you clicked an item in the group')
  const data = event.target.value
  console.log('clicked this data:', data)
  this.setState({searchLink: event.target.value})
  console.log(this.state.searchLink)
}

But can't seem to get it to work. Probably been staring at this way too long. Appreciate the help guys.

LoF10
  • 1,907
  • 1
  • 23
  • 64
  • state updates are asynchronous. So logging right after the `setState` will just give you the old value, use the callback for `setState` – Agney Oct 18 '19 at 18:36
  • I'm looking at the react-bootstrap documentation, and I don't see any parameter for `value`. – Jay Jordan Oct 18 '19 at 18:38

1 Answers1

0

Match.js

import React from 'react';
import { ListGroup } from 'react-bootstrap';

const match = ({ alertClicked, address }) => {

return (
    <ListGroup.Item 
        className="Matches"
        action 
        // function expressions could cause this to rerender unnecessarily.
        onClick={(address) => alertClicked(address)}> 
          <p>{`${address}`}</p>
    </ListGroup.Item>
)

Other.js

alertClicked = address => {
    event.preventDefault(); // not sure what event you're preventing
    this.setState({searchLink: address});
}

If you're worried about the unnecessary rendering, you should look for another method of achieving this functionality with a more defined element/component.

Jay Jordan
  • 643
  • 4
  • 16