Я хочу изменить состояние при нажатии кнопки в React. По сути, я пытаюсь обновить значение имени, отображаемого в моем div, установив this.state.name равным тому, что введено в текстовое поле.
Что я здесь делаю неправильно?
Я также не совсем понимаю разницу между onClick = {() => this.updateText()} и onClick = {this.updateText()} и/или onClick = {this.updateText}. Может, это связано с этим?
Форма.tsx
import React from 'react';
export default class Form extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
title: "Enter a new name here",
description: "Hola",
textInput: null,
name: this.props.name
};
}
updateText() {
this.setState({
name: this.state.textInput
});
}
render() {
return (
<div className = "App">
<div>{this.props.text} {this.state.name}</div>
<div>{this.state.age}</div>
<input type = "text" placeholder = {this.state.title}>{this.state.textInput}</input>
<br />
<button type = "submit" onClick = {() => this.updateText()}>Submit</button>
</div>
);
}
}
App.tsx
import React from 'react';
import './App.css';
import Form from "./Form";
class App extends React.Component {
render() {
return (
<div className = "App">
<Form text = "Hello" age = {22} name = "Thomas"/>
</div>
);
}
}
export default App;
this.state.name отображается как пустое или нулевое при вводе чего-либо и нажатии кнопки отправки.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как сказал @Alexander Staroselsky в своем комментарии, вы должны использовать обработчик onChange для ввода. Таким образом, вы можете обновить textInput и установить его на свое значение name.
{this.updateText()} не является правильным способом использования обработчика. Если вы используете его таким образом, он вызывается при каждом рендеринге, но не при щелчке.
onClick = {this.updateText} Здесь вы можете использовать ссылку на функцию, и она работает. Но либо вы должны связать его в конструкторе, либо определить его как функцию стрелки. Вы можете увидеть пример ниже.
onClick = {() => this.updateText()} Это вариант его использования. Вы используете здесь функцию стрелки для своего обработчика. Он также работает без привязки функции обработчика для this. Но таким образом ваша функция-обработчик воссоздается при каждом рендеринге. По возможности избегайте этого.
class App extends React.Component {
render() {
return (
<div className = "App">
<Form text = "Hello" age = {22} name = "Thomas"/>
</div>
);
}
}
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "Enter a new name here",
description: "Hola",
textInput: "",
name: this.props.name
};
}
updateText = () => {
this.setState({
name: this.state.textInput
});
}
handleChangeEvent = (e) => this.setState({ textInput: e.target.value})
render() {
return (
<div className = "App">
<div>{this.props.text} {this.state.name}</div>
<div>{this.state.age}</div>
<input value = {this.state.textInput} onChange = {this.handleChangeEvent} type = "text" placeholder = {this.state.title} />
<br />
<button type = "submit" onClick = {this.updateText}>Submit</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id = "root" />Это работает! Что мне кажется интересным, так это два разных способа сделать это. На мой взгляд, я предпочитаю следующий подход, который представляет собой небольшое синтаксическое изменение по сравнению с вами. Но, по крайней мере, для меня это кажется немного более кратким. Интересно, производительность такая же?
<input type = "text" placeholder = {this.state.title} value = {this.state.textInput} onChange = {(e) => this.handleChangeEvent(e)}/> <br /> <button type= "отправить" onClick = {() => this.updateText()}>Отправить</button>
updateText() { this.setState({ name: this.state.textInput, textInput: "" }); } handleChangeEvent(e: any) { this.setState({ textInput: e.target.value}) }
@MisterTams, по-вашему, функции обработчика будут воссоздаваться при каждом рендеринге. Вы можете прочитать этот ответ, чтобы увидеть разницу. (Кстати, принятый ответ вводит в заблуждение, вы можете прочитать комментарии). Но для небольших приложений (я имею в виду, если не так много компонентов с такими функциями) производительность будет почти такой же.
Я все еще не совсем уверен, что понимаю. Значит, ваш фрагмент кода тоже не подходит для этого? Хорошо ли передать обработчик в качестве опоры от родительского к дочернему компоненту? Синтаксис () => смущает меня, потому что я не работаю с React или JavaScript.
Мой пример — правильный подход в качестве вашего последнего кода. Использование {() => someFunc()} вызывает воссоздание при каждом рендеринге, поскольку вы используете функцию стрелки в обработчике. Но {someFunc} — это пример использования по ссылке и не вызывает воссоздание. Ваш пример также в порядке, поскольку вы используете функции по их ссылке. Единственная разница между вашим примером и моим заключается в том, что вы используете обычные функции и привязываете их в конструкторе, а я использую стрелочные функции, поэтому не нужно привязывать их для контекста this. Я знаю, здесь разные темы. Но через некоторое время вы поймете разницу.
Таким образом, в основном мой немного другой подход с использованием функции стрелки в обработчике, таком как onChange = {(e) => this.handleChangeEvent(e)}, вызовет вызов этой функции в любое время, когда что-либо в этом компоненте требует повторного рендеринга. Ваш код в ответе, который я выбрал как принятый, будет давать тот же результат, но не будет автоматически вызывать onChange или onClick каждый раз, когда что-то в этом компоненте требует повторного рендеринга. Поэтому ваш первоначальный ответ имеет тот же эффект, но немного лучше по производительности. Это правильно? Ссылку, которую вы дали, я тоже прочитаю.
Не совсем «звонить» или «вызывать», а «отдыхать». Это не влияет на сам компонент, но вызывает ненужный повторный рендеринг дочерних компонентов. Я попытался объяснить это в первой ссылке, которую я дал в своем первом комментарии здесь. Так что кроме слова "вызвать" вы правильно думаете. (Кстати, {someFunc()} вызывает или вызывает функцию немедленно, но обработчики onClick так не работают. Таким образом, вы никогда не используете обработчик таким образом.)
Потрясающий! Я читал об этом последние несколько минут. Вы здорово помогли! Спасибо!
Вам нужно добавить обработчик изменений к самому входу. Значение остается нулевым, потому что вы на самом деле не обновляете состояние по мере того, как происходят изменения. reactjs.org/docs/forms.html. Также входы не являются блочными элементами. У них нет детей или эквивалента. Они самозакрывающиеся.