So, I'm trying to show an Amazon country API to my React-Select component and I've tried to do this in many different ways, but I would only get as result a blank page or a white list on my Select component
The code below has only the Axios method to call the API.
What Should I do so I can show the API data on the Select component?
Here's my Form.jsx component:
import { useState, useEffect } from 'react';
import '../App.css';
import Form from 'react-bootstrap/Form';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Button from 'react-bootstrap/Button';
import Select from 'react-select';
import Axios from 'axios';
function Forms() {
const [countries, setCountry] = useState([])
Axios.get(`https://amazon-api.sellead.com/country`)
.then(res => {
const countries = res.data;
console.log(countries)
})
return (
<Form>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridEmail">
<Form.Control type="text" name = "name" placeholder="Nome" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="email" name = "email" placeholder="E-mail" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name = "cpf" placeholder="CPF" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name = "tel" placeholder="Telefone" />
</Form.Group>
<Form.Label>País</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
<Select
/>
</Form.Group>
<Form.Label>Cidade</Form.Label>
<Form.Group as={Col} controlId="formGridPassword"> <br/>
<Select
/>
</Form.Group>
<Button variant="primary" type="submit">
Enviar
</Button>
</Row>
</Form>
);
}
export default Forms;
CodePudding user response:
- Hey, First of all, you have to understand that you have to store that data somewhere, The data that you received from API.
- Once you store it all you need is just update that in
useState([])
. That you created. - Now this API you are calling must be called once only so all we need is
useEffect()
hook with[]
an empty array as a dependency so it will only call once the function that is handling API, on initial render. - Once you have data then just loop through it using the map function and render the options.
- Here is code.
App.js
import "./styles.css";
import Forms from "./Forms.js";
export default function App() {
return (
<div className="App">
<Forms />
</div>
);
}
Forms.js
import { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
import Col from "react-bootstrap/Col";
import Row from "react-bootstrap/Row";
import Button from "react-bootstrap/Button";
import Select from "react-select";
import Axios from "axios";
function Forms() {
// creating an useState for setting country list received from api
const [countriesList, setCountriesLits] = useState([]);
//async funtion that handling api
const getCountries = async () => {
let contries = []; // to store api data
const countryRes = await Axios.get(
`https://amazon-api.sellead.com/country`
);
countryRes.data.forEach((data) => {
contries.push(data.name);
});
// updating state
setCountriesLits(contries);
};
const handleChange = (e) => {
alert(e.target.value);
};
useEffect(() => {
getCountries();
}, []);
return (
<Form>
<Row className="mb-3">
<Form.Group as={Col} controlId="formGridEmail">
<Form.Control type="text" name="name" placeholder="Nome" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="email" name="email" placeholder="E-mail" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name="cpf" placeholder="CPF" />
</Form.Group>
<Form.Group as={Col} controlId="formGridPassword">
<Form.Control type="text" name="tel" placeholder="Telefone" />
</Form.Group>
<Form.Label>País</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
<select onChange={handleChange}>
{/* rendering option from the state countriesList */}
{countriesList.map((data, i) => (
<option key={i} value={data}>
{data}
</option>
))}
</select>
</Form.Group>
<Form.Label>Cidade</Form.Label>
<Form.Group as={Col} controlId="formGridPassword">
{" "}
<br />
<Select />
</Form.Group>
<Button variant="primary" type="submit">
Enviar
</Button>
</Row>
</Form>
);
}
export default Forms;
You can also visit the working code here on
CodePudding user response:
All you're doing is logging the data to the console (and shadowing a variable):
const countries = res.data;
console.log(countries)
If the data needs to be set in state, set it in state (and you don't need the local variable at all):
setCountry(res.data);
You've also removed the prop from your <Select>
component. Clearly you'll need that back:
<Select options={countries} />
As an aside... Names matter. There is a pluralization inconsistency here:
const [countries, setCountry] = useState([])
It's best to keep your names consistent and meaningful, otherwise you end up confusing yourself when you try to use the data. Since this is an array of values, maintain pluralization:
const [countries, setCountries] = useState([]);