onKeyUp 在 React 中不起作用,而 onChange 起作用了
onKeyUp not working in React where onChange did
我正在做一个 React 编码挑战,需要在 KeyUp 上更新一个值。我最初将其设置为更新 onChange,但测试需要 onKeyUp,所以我尝试将其更改为那个,但我的字段不再更新,我无法在文本区域中输入任何内容。
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
this.setState({ value: event.target.value })
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{marked(this.state.value)}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
就像我说的,当它是 onChange 并且我的函数是 handleChange 时它工作正常,但是因为我切换它我不能输入任何东西。
由于事件发生在文本框的实际值更改之前,因此 event.target.value
的结果是一个空字符串。使用空字符串设置状态,清除文本框。
您需要从事件中获取按下的键值,并将其添加到现有的state.value
。
注意:我已经从演示中删除了 marked
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
const keyValue = event.key;
this.setState(({ value }) => ({
value: value + keyValue
}))
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{this.state.value}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
您可以通过不给它 value
并简单地将值存储在 ref
的状态中来使文本区域不受控制。
示例 (CodeSandbox)
class MarkdownApp extends React.Component {
ref = null;
state = {
value: ""
};
handleKeyUp = event => {
this.setState({ value: this.ref.value });
};
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea
onKeyUp={this.handleKeyUp}
ref={ref => (this.ref = ref)}
id="editor"
/>
<br />
</label>
<label>
Your markup will be previewed here:
<p id="preview">{marked(this.state.value)}</p>
</label>
</form>
);
}
}
我只想从文本区域中删除 value
属性。因为如果您将 value 属性放入其中,那么用户将无法以交互方式更改它。该值将始终保持固定(除非您明确更改代码中的值)。您不需要使用 React 来控制它——DOM 将为您保留该值。
我在下面所做的唯一更改是从 textarea 元素中删除 value={this.state.value}
:
import React from 'react';
import ReactDOM from 'react-dom';
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
this.setState({ value: event.target.value })
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{this.state.value}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
问题是您有两种方式将 state = 绑定到文本框中的值。 OnChange 会在进行更改并且事件触发后更新您的状态。 Onkeyup returns 值 onkeyup 并且由于您将其映射到您的状态,因此它将保持为空。删除 value 道具,它应该可以工作。
我正在做一个 React 编码挑战,需要在 KeyUp 上更新一个值。我最初将其设置为更新 onChange,但测试需要 onKeyUp,所以我尝试将其更改为那个,但我的字段不再更新,我无法在文本区域中输入任何内容。
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
this.setState({ value: event.target.value })
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{marked(this.state.value)}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
就像我说的,当它是 onChange 并且我的函数是 handleChange 时它工作正常,但是因为我切换它我不能输入任何东西。
由于事件发生在文本框的实际值更改之前,因此 event.target.value
的结果是一个空字符串。使用空字符串设置状态,清除文本框。
您需要从事件中获取按下的键值,并将其添加到现有的state.value
。
注意:我已经从演示中删除了 marked
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
const keyValue = event.key;
this.setState(({ value }) => ({
value: value + keyValue
}))
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{this.state.value}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
您可以通过不给它 value
并简单地将值存储在 ref
的状态中来使文本区域不受控制。
示例 (CodeSandbox)
class MarkdownApp extends React.Component {
ref = null;
state = {
value: ""
};
handleKeyUp = event => {
this.setState({ value: this.ref.value });
};
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea
onKeyUp={this.handleKeyUp}
ref={ref => (this.ref = ref)}
id="editor"
/>
<br />
</label>
<label>
Your markup will be previewed here:
<p id="preview">{marked(this.state.value)}</p>
</label>
</form>
);
}
}
我只想从文本区域中删除 value
属性。因为如果您将 value 属性放入其中,那么用户将无法以交互方式更改它。该值将始终保持固定(除非您明确更改代码中的值)。您不需要使用 React 来控制它——DOM 将为您保留该值。
我在下面所做的唯一更改是从 textarea 元素中删除 value={this.state.value}
:
import React from 'react';
import ReactDOM from 'react-dom';
class MarkdownApp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleKeyUp = this.handleKeyUp.bind(this);
}
handleKeyUp(event) {
this.setState({ value: event.target.value })
}
render() {
return (
<form>
<label>
Enter your markdown here:
<br />
<textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
<br />
</label>
<label>
Your markup will be previewed here:
<p id='preview'>{this.state.value}</p>
</label>
</form>
);
}
}
ReactDOM.render(
<MarkdownApp />,
document.getElementById('root')
);
问题是您有两种方式将 state = 绑定到文本框中的值。 OnChange 会在进行更改并且事件触发后更新您的状态。 Onkeyup returns 值 onkeyup 并且由于您将其映射到您的状态,因此它将保持为空。删除 value 道具,它应该可以工作。