I have my react-bootstrap-typeahead setup like this:
// MusicServices.jsx
import React, {Fragment, useState} from 'react';
import { Form } from 'react-bootstrap';
import { Typeahead } from 'react-bootstrap-typeahead';
const MusicServices = ({services}) => {
const [musicServiceID, setMusicServiceSelection] = useState([]);
const [transferDetailID, setTransferDetailSelection] = useState([]);
const musicServiceDetails = Object.keys(services).map((serviceID) => {
return {
id: serviceID,
name: services[serviceID].name
}
});
const getTransferDetails = () => {
let transferDetailSelections = []
if (musicServiceID.length) {
transferDetailSelections = services[musicServiceID[0].id].transferDetails;
}
return (
<Form.Group>
<Form.Label>Transfer Details</Form.Label>
<Typeahead
name="transferdetail"
id="transfer-detail"
labelKey="name"
onChange={setTransferDetailSelection}
options={transferDetailSelections}
placeholder="Choose a Transfer Detail..."
selected={transferDetailID}
/>
</Form.Group>
)
}
return (
<Fragment>
<Form.Group>
<Form.Label>Music Services</Form.Label>
<Typeahead
name="musicservice"
id="music-service"
labelKey="name"
onChange={(selected) => {
setMusicServiceSelection(selected)
}}
options={musicServiceDetails}
placeholder="Choose a music service..."
selected={musicServiceID}
/>
</Form.Group>
{getTransferDetails()}
</Fragment>
);
};
export default MusicServices;
I use the same code ina. few places so I extracted it out to it's own function...
SO I use it in a form like this:
import React from 'react';
const Jumbotron = require('react-bootstrap').Jumbotron;
const Container = require('react-bootstrap').Container;
import Form from 'react-bootstrap/Form';
const Button = require('react-bootstrap').Button;
import MusicServices from '../../components/auth/MusicServices';
const Generate = ({services}) => {
const handleSubmit = (event) => {
const formEvent = event.currentTarget;
console.log(event.target.elements)
event.preventDefault();
event.stopPropagation();
};
let mservices = {123455: {name: 'abc', transferDetails: [{id: 6789, name: 'der'}]}}
return (
<>
<Jumbotron>
<Container>
<h1 className="display-3">Generate</h1>
<p>{session.user.name}, this will generate a new key pair to be stored on the filestore and against a transfer detail.</p>
</Container>
</Jumbotron>
<Container>
<Form onSubmit={handleSubmit}>
<Form.Group controlId="service">
<MusicServices services={mservices}></MusicServices>
</Form.Group>
<Button variant="primary" type="submit">
Generate key pair
</Button>
</Form>
</Container>
</>
)
}
export default Generate
In my handleSubmit()
function, I want to get the value of the transfer-detail
typeahead, but the value is coming back as "der". What I really want is the "6789" id value, with the "der" being displayed to the user to typeahead on.
I can't see how to get this value. At a guess it's in transferDetailID
, but that doesn't seem available in my Generate.jsx page.
The useState
hooks need to be in the parent and passed down to the child, so in this instance, they need to be taken from the MusicServices
functional Component and put into the Generate
functional Component.
You then have to pass both the variable and the setter through to the child. So in the Generate
functional component I have changed the code:
const Generate = ({services}) => {
const [musicServiceID, setMusicServiceSelection] = useState([]);
const [transferDetailID, setTransferDetailSelection] = useState([]);
return (
<>
...
<Container>
<Form onSubmit={handleSubmit}>
<Form.Group controlId="service">
{
MusicServices(
services,
musicServiceID,
setMusicServiceSelection,
transferDetailID,
setTransferDetailSelection
)
}
</Form.Group>
</Form>
</Container>
...
</>
)
};
this then allows the handleSubmit
function access to the states of musicServiceID
and transferDetailID
.