#javascript #reactjs
#javascript #reactjs
Вопрос:
Я хочу получать входные данные от пользователя с помощью кнопки в App.js , извлекает некоторую информацию (идентификатор данных) из API сайта, а затем использует полученную информацию (идентификатор) для отображения желаемой информации пользователю путем отправки идентификатора в Population.js но это просто работает неправильно. Я думаю, что, вероятно, componentDidUpdate нуждается в каком-то аргументе, потому что запрос на выборку, который я должен отправить, требует пользовательского ввода для работы.Кроме того, я думаю, что мой код извлекает информацию еще до того, как пользователь нажимает кнопку, потому что консоль не отображает правильный идентификатор, который мне нужен (он отображает 4-5 значений, и все они неверны). Он отлично работает, если я жестко закодирую значения.По сути, я хочу принимать входные данные через button, использовать эти входные данные для извлечения чего-либо, затем использовать извлеченную вещь для извлечения чего-либо еще, а затем отображать полученную информацию. Пожалуйста, помогите мне. Я новичок в React. Вот APP.js
import React from 'react';
import './App.css';
import Population from './Population.js';
class App extends React.Component {
constructor(props) {
super(props);
this.state = { name: "" ,info : {},formSubmit: false};
this.handleInput = this.handleInput.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleInput (event) {
console.log(event.target.value);
}
handleFormSubmit (event) {
event.preventDefault();
console.log("the value " event.target.value);
this.setState({formSubmit: true,name : event.target.value});
}
componentDidMount(){//the value property needs to be fetched from user
fetch(`https://wft-geo-db.p.rapidapi.com/v1/geo/cities?namePrefix=${value}`, {
"method": "GET",
"headers": {
"x-rapidapi-key": "c4ab967692mshc65dd5c6e10a987p1790bejsn81ea7b831444",
"x-rapidapi-host": "wft-geo-db.p.rapidapi.com"
}
})
.then(response => response.json())
.then(data => {
const newInfo = data.data;
const newName = newInfo[0].wikiDataId;
const newState = Object.assign({},this.state,{
info : newInfo,
name : newName
});
this.setState(newState);
console.log("The sent code " this.state.name);
})
.catch(err => {
console.error(err);
});
}
render () {
return (
<div className="App">
<h1>
Enter the name of the city: <br/>
</h1>
<form >
<label>
Enter the city name to get the population:{" "}
<input
type="text"
/>
<button onClick = {this.handleFormSubmit}>Enter</button>
</label>
</form>
{this.state.formSubmit amp;amp; <Population name={this.state.name} />}
</div>
);
}
}
export default App;
и вот Population.js
import React from 'react';
import "./App.css";
class Population extends React.Component{
constructor(props){
super(props);
this.state = {
info : {},
population : 0,
}
this.getPopulation = this.getPopulation.bind(this);
}
getPopulation(name){
fetch(`https://wft-geo-db.p.rapidapi.com/v1/geo/cities/${name}`, {
"method": "GET",
"headers": {
"x-rapidapi-key": "c4ab967692mshc65dd5c6e10a987p1790bejsn81ea7b831444",
"x-rapidapi-host": "wft-geo-db.p.rapidapi.com"
}
})
.then(response => response.json())
.then((data) => {
const newInfo = data.data;
const newPopulation = newInfo.population;
const newState = Object.assign({},this.state,{
info : newInfo,
population : newPopulation
});
this.setState(newState);
console.log(this.state.info);
})
.catch(error => {
console.error(error);
});
}
componentDidMount(){
this.getPopulation(this.props.name);
console.log("The name " this.props.name);
}
render(){
return (
<div className="App">
The population is {this.state.population}
</div>
);
}
}
export default Population;
Комментарии:
1. У вас есть выборка в обоих компонентах, какой из них вы хотите использовать для вызова службы? и вы говорите, что вам нужен пользовательский ввод, как вы это получаете?
2. Я использую кнопку в App.js чтобы получить входные данные. Входные данные будут использоваться для извлечения идентификатора в методе componentDidMount в App.js и этот ввод будет передан в Pollution.js для получения и отображения необходимых данных
Ответ №1:
Ваше требование отличается, и вам не нужно использовать componentDidMount здесь, поскольку вы собираетесь выполнить вызов службы после того, как пользователь нажмет кнопку поиска.
Я изменил ваш код для работы при нажатии кнопки, и он передает код компоненту population, который выполняет вызов api как для componentDidMount, так и для componentDidUpdate, поскольку код может быть обновлен в будущем
class App extends React.Component {
constructor(props) {
super(props);
this.state = { name: "", info: {}, formSubmit: false, code: "" };
this.handleInput = this.handleInput.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleInput(event) {
console.log(event.target.value);
this.setState({ name: event.target.value, formSubmit: false });
}
handleFormSubmit(event) {
event.preventDefault();
fetch(
`https://wft-geo-db.p.rapidapi.com/v1/geo/cities?namePrefix=${this.state.name}`,
{
method: "GET",
headers: {
"x-rapidapi-key":
"",
"x-rapidapi-host": "wft-geo-db.p.rapidapi.com"
}
}
)
.then((response) => response.json())
.then((data) => {
const newInfo = data.data;
const newName = newInfo[0].wikiDataId;
const newState = Object.assign({}, this.state, {
info: newInfo[0],
code: newName,
formSubmit: true
});
this.setState(newState);
console.log("The sent code " this.state.name);
})
.catch((err) => {
console.error(err);
});
}
componentDidUpdate() {
//the value property needs to be fetched from user
}
render() {
return (
<div className="App">
<h1>
Enter the name of the city: <br />
</h1>
<form>
<label>
Enter the city name to get the population:{" "}
<input
type="text"
value={this.state.name}
onChange={this.handleInput}
/>
<button onClick={this.handleFormSubmit}>Enter</button>
</label>
</form>
{this.state.formSubmit amp;amp; <Population name={this.state.code} />}
</div>
);
}
}
И компонент заполнения будет выглядеть так
class Population extends React.Component {
constructor(props) {
super(props);
this.state = {
info: {},
population: 0
};
this.getPopulation = this.getPopulation.bind(this);
}
getPopulation(name) {
fetch(`https://wft-geo-db.p.rapidapi.com/v1/geo/cities/${name}`, {
method: "GET",
headers: {
"x-rapidapi-key": "",
"x-rapidapi-host": "wft-geo-db.p.rapidapi.com"
}
})
.then((response) => response.json())
.then((data) => {
const newInfo = data.data;
const newPopulation = newInfo.population;
const newState = Object.assign({}, this.state, {
info: newInfo,
population: newPopulation
});
this.setState(newState);
console.log(this.state.info);
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
if (this.props.name) {
this.getPopulation(this.props.name);
console.log("The name " this.props.name);
}
}
componentDidUpdate() {
if (this.props.name) {
this.getPopulation(this.props.name);
console.log("The name " this.props.name);
}
}
render() {
return <div className="App">The population is {this.state.population}</div>;
}
}
Комментарии:
1. Я удалил ключ api из ответа как его общедоступный
2. Спасибо. Это послужило моей цели. Я понял. Есть ли какой-либо способ, которым я могу сделать Population.js подождите некоторое время, а затем отправьте запрос на выборку, когда он получит код? .Прямо сейчас я думаю, как только он получает код, он отправляет запрос на выборку. Веб-сайт разрешает 1 запрос в секунду, поэтому консоль сообщает, что я превысил свои запросы
3. вы можете использовать setTimeout и сделать это через определенное время
4. Большое спасибо. Хотя я никогда не слышал об этом раньше. Но это должно сработать. Спасибо 🙂
Ответ №2:
Функция componentDidMount вызывается, как только компонент монтируется, и, следовательно, она выполняет операцию выборки, как только компонент монтируется. Если вы хотите, чтобы операция выборки выполнялась при нажатии кнопки, вам нужно будет поместить код внутри пользовательской функции и вызвать ее при нажатии кнопки. Я не думаю, что вы можете передать какие-либо реквизиты компоненту did mount, поскольку вы не можете контролировать, когда он вызывается. componentDidUpdate может быть вам полезен componentDidUpdate