输入 onChange() 事件未被调用
Input onChange() event is not called
我正在渲染 type='number'
的 Input
。
输入的值为this.state.value
。
输入和所有 UI 组件都是通过 Semantic-UI 生成的,但我认为这并不重要重要性信息。
我还有一个自定义箭头菜单用于此输入而不是原始的。 [数字类型的输入有两个指向 decrease/increase 值的箭头]
渲染()
render() {
// Custom Menu
const arrowsMenu = (
<Menu compact size='tiny'>
<Menu.Item as='a' onClick={ this.decreaseNumber.bind(this) }>
<Icon name='chevron left' size='small' />
</Menu.Item>
<Menu.Item as='a' onClick={ this.increaseNumber.bind(this) }>
<Icon name='chevron right' size='small' />
</Menu.Item>
</Menu>
);
return (
<Input value={ this.state.value } type="number" label={ arrowsMenu } placeholder="Raplece ma" onChange={ this.onChange.bind(this) } />
);
}
自定义菜单使用这两个函数:
decreaseNumber(e) {
this.setState({
value: this.state.value - 1
});
}
increaseNumber(e) {
this.setState({
value: this.state.value + 1
});
}
onChange
你可以放置任何东西。
onChange(e) {
console.log('====================================');
console.log('Hello pals');
console.log('====================================');
}
问题是
每当我 从 Menu
推箭头 时, Input
的 onChange()
事件是 不触发。但是输入的值是改变。
(当然是因为this.state.value
变量在state里变了)
如果我对原来的箭头做同样的事情,当然,值会改变。
为什么会这样,我该如何解决?
onChange
仅在用户进入输入组件并与其交互以更改值时调用(例如,如果他们输入新值)。如果您通过其他途径以编程方式更改值(在您的示例中通过自定义菜单更改它),则不会调用 onChange
。
这是按预期设计工作的。
如果您想触发 onChange,请从您的 increaseNumber
和 decreaseNumber
方法中调用它。
您可以使用您想要的任何代码调用 onChange
,但是如果您想要反映新值,您需要根据事件的新输入值设置状态。
至于 decreaseNumber
和 increaseNumber
你也需要改变状态但是在这里你正在进行计算所以你需要确保它是一个数字(或将它转换为数字)因为你得到一个字符串从活动回来。
工作示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
onChange = e => this.setState({value: e.target.value});
increaseNumber = () => this.setState({value: Number(this.state.value) + 1});
decreaseNumber = () => this.setState({ value: Number(this.state.value) - 1 });
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.decreaseNumber}>-</button>
<input type="number" value={value} onChange={this.onChange}/>
<button onClick={this.increaseNumber}>+</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
编辑
要触发 onChange
处理程序,只需调用 this.onChange
但请注意,您不能像本机事件处理程序那样传递事件,但您可以传递一个简单的 object 来模拟正常的 [=21] =] object 与 target.value
.
另一种选择是尝试通过 ref
触发它,但请记住,在某些情况下它可能会导致无限循环。
编辑示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
onChange = (e) => {
this.setState({ value: e.target.value });
console.log('change', e.target.value);
}
increaseNumber = () => {
const { value } = this.state;
const nextValue = Number(value) + 1;
const changeEvent = {
target: {
value: nextValue
}
};
this.onChange(changeEvent);
}
decreaseNumber = () => {
const { value } = this.state;
const nextValue = Number(value) - 1;
const changeEvent = {
target: {
value: nextValue
}
};
this.onChange(changeEvent);
}
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.decreaseNumber}>-</button>
<input type="number" value={value} onChange={this.onChange} />
<button onClick={this.increaseNumber}>+</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
编辑 #2
作为您评论的跟进:
list's value is its content/children. If some of the children change,
then list changes with them as well
好吧,这有一个简单的解决方案,您可以使用 ref
(就像我在回答的第一部分中提到的那样)并使用 bubbles:true
发送一个事件,这样它就会冒泡所有一直到 parents.
使用您的新示例代码:
class App extends React.Component {
liOnChange(e) {
console.log('listed item/items changed');
}
inputOnChange(e) {
console.log('input changed');
}
handleClick(e){
var event = new Event("input", { bubbles: true });
this.myInput.dispatchEvent(event);
}
render() {
return(
<div>
<ul>
<li onChange={this.liOnChange.bind(this)}>
<input ref={ref => this.myInput = ref} type='text'onChange={this.inputOnChange.bind(this)}/>
<button onClick={this.handleClick.bind(this)}>+</button>
</li>
</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我一般不喜欢使用参考,但有时你需要它们。
我正在渲染
type='number'
的Input
。输入的值为
this.state.value
。输入和所有 UI 组件都是通过 Semantic-UI 生成的,但我认为这并不重要重要性信息。
我还有一个自定义箭头菜单用于此输入而不是原始的。 [数字类型的输入有两个指向 decrease/increase 值的箭头]
渲染()
render() {
// Custom Menu
const arrowsMenu = (
<Menu compact size='tiny'>
<Menu.Item as='a' onClick={ this.decreaseNumber.bind(this) }>
<Icon name='chevron left' size='small' />
</Menu.Item>
<Menu.Item as='a' onClick={ this.increaseNumber.bind(this) }>
<Icon name='chevron right' size='small' />
</Menu.Item>
</Menu>
);
return (
<Input value={ this.state.value } type="number" label={ arrowsMenu } placeholder="Raplece ma" onChange={ this.onChange.bind(this) } />
);
}
自定义菜单使用这两个函数:
decreaseNumber(e) {
this.setState({
value: this.state.value - 1
});
}
increaseNumber(e) {
this.setState({
value: this.state.value + 1
});
}
onChange
你可以放置任何东西。
onChange(e) {
console.log('====================================');
console.log('Hello pals');
console.log('====================================');
}
问题是
每当我 从 Menu
推箭头 时, Input
的 onChange()
事件是 不触发。但是输入的值是改变。
(当然是因为this.state.value
变量在state里变了)
如果我对原来的箭头做同样的事情,当然,值会改变。
为什么会这样,我该如何解决?
onChange
仅在用户进入输入组件并与其交互以更改值时调用(例如,如果他们输入新值)。如果您通过其他途径以编程方式更改值(在您的示例中通过自定义菜单更改它),则不会调用 onChange
。
这是按预期设计工作的。
如果您想触发 onChange,请从您的 increaseNumber
和 decreaseNumber
方法中调用它。
您可以使用您想要的任何代码调用 onChange
,但是如果您想要反映新值,您需要根据事件的新输入值设置状态。
至于 decreaseNumber
和 increaseNumber
你也需要改变状态但是在这里你正在进行计算所以你需要确保它是一个数字(或将它转换为数字)因为你得到一个字符串从活动回来。
工作示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
onChange = e => this.setState({value: e.target.value});
increaseNumber = () => this.setState({value: Number(this.state.value) + 1});
decreaseNumber = () => this.setState({ value: Number(this.state.value) - 1 });
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.decreaseNumber}>-</button>
<input type="number" value={value} onChange={this.onChange}/>
<button onClick={this.increaseNumber}>+</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
编辑
要触发 onChange
处理程序,只需调用 this.onChange
但请注意,您不能像本机事件处理程序那样传递事件,但您可以传递一个简单的 object 来模拟正常的 [=21] =] object 与 target.value
.
另一种选择是尝试通过 ref
触发它,但请记住,在某些情况下它可能会导致无限循环。
编辑示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
}
onChange = (e) => {
this.setState({ value: e.target.value });
console.log('change', e.target.value);
}
increaseNumber = () => {
const { value } = this.state;
const nextValue = Number(value) + 1;
const changeEvent = {
target: {
value: nextValue
}
};
this.onChange(changeEvent);
}
decreaseNumber = () => {
const { value } = this.state;
const nextValue = Number(value) - 1;
const changeEvent = {
target: {
value: nextValue
}
};
this.onChange(changeEvent);
}
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.decreaseNumber}>-</button>
<input type="number" value={value} onChange={this.onChange} />
<button onClick={this.increaseNumber}>+</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
编辑 #2
作为您评论的跟进:
list's value is its content/children. If some of the children change, then list changes with them as well
好吧,这有一个简单的解决方案,您可以使用 ref
(就像我在回答的第一部分中提到的那样)并使用 bubbles:true
发送一个事件,这样它就会冒泡所有一直到 parents.
使用您的新示例代码:
class App extends React.Component {
liOnChange(e) {
console.log('listed item/items changed');
}
inputOnChange(e) {
console.log('input changed');
}
handleClick(e){
var event = new Event("input", { bubbles: true });
this.myInput.dispatchEvent(event);
}
render() {
return(
<div>
<ul>
<li onChange={this.liOnChange.bind(this)}>
<input ref={ref => this.myInput = ref} type='text'onChange={this.inputOnChange.bind(this)}/>
<button onClick={this.handleClick.bind(this)}>+</button>
</li>
</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我一般不喜欢使用参考,但有时你需要它们。