Javascript React本地听写在iOS上突然切字
在iOS中对文本输入使用听写时,听写会在单词之间突然结束。这不是以前React Native 53上的问题。移动到版本54+会导致此行为 下面是产生错误的代码示例:Javascript React本地听写在iOS上突然切字,javascript,ios,reactjs,react-native,Javascript,Ios,Reactjs,React Native,在iOS中对文本输入使用听写时,听写会在单词之间突然结束。这不是以前React Native 53上的问题。移动到版本54+会导致此行为 下面是产生错误的代码示例: import React, { Component } from 'react'; import { TextInput } from 'react-native'; export default class App extends Component { state = { value: '' } onChangeTex
import React, { Component } from 'react';
import { TextInput } from 'react-native';
export default class App extends Component {
state = { value: '' }
onChangeText = value => console.log(value) || this.setState({ value })
render() {
return (
<TextInput
onChangeText={this.onChangeText}
value={this.state.value}
style={{ borderWidth: 2, borderColor: 'black', width: 200, height: 48 }}
/>
);
}
}
import React,{Component}来自'React';
从“react native”导入{TextInput};
导出默认类应用程序扩展组件{
状态={值:“”
onChangeText=value=>console.log(value)| | this.setState({value})
render(){
返回(
);
}
}
它似乎来自onChangeText
方法,因为当我将函数onChangeText
放入onBlur
方法时,它工作得很好。
但是使用onBlur
使得不可能使用onEditing
或onSubmitEditing
,因为它在onEditing
和onSubmitEditing
方法之后触发setState
有人找到了解决办法吗
github react native项目上出现了一个问题。因此这是react native的一个短消息 口述失败的原因是,当您口述时,组件会重新呈现它自己。当它重新呈现时,Siri面板最小化,因此听写突然结束 为了解决这个问题,我创建了一个TextInput包装器组件,该组件依赖于
shouldComponentUpdate
在值更改时阻止我的TextInput包装器重新呈现
现在,我们不是立即重新渲染,而是仅在特定时间量的去抖动后设置状态。(500-1500之间的任何值都可以)
试试看,让我知道它是否适合你
import React from 'react';
import debounce from 'lodash.debounce';
import PropTypes from 'prop-types';
import { TextInput } from 'react-native';
const CHANGE_TEXT_DELAY_UNTIL_DISPATCH = 700;
// enforces dication safety so that siri can hear more than 1 words
class DictationSafeTextInput extends React.Component {
//
constructor(props) {
super(props);
this.onValueChangeDelayed =
debounce(this.onValueChangeDelayed.bind(this), CHANGE_TEXT_DELAY_UNTIL_DISPATCH);
this.state = {
value: props.value,
};
}
componentWillReceiveProps(nextProps) {
if (this.props.value !== nextProps.value) {
this.onValueChangeDelayed(nextProps.value);
}
}
shouldComponentUpdate(nextProps, nextState) {
const pastProps = this.props;
const shoudlUpdate = (
// pastProps.value !== nextProps.value
// ||
nextState.value !== this.state.value
||
pastProps.style !== nextProps.style
||
pastProps.editable !== nextProps.editable
||
pastProps.onContentSizeChange !== nextProps.onContentSizeChange
||
pastProps.onSubmitEditing !== nextProps.onSubmitEditing
||
pastProps.onChangeText !== nextProps.onChangeText
||
pastProps.onFocus !== nextProps.onFocus
||
pastProps.onBlur !== nextProps.onBlur
||
pastProps.innerTextInputRef !== nextProps.innerTextInputRef
||
pastProps.blurOnSubmit !== nextProps.blurOnSubmit
||
pastProps.autoFocus !== nextProps.autoFocus
||
pastProps.pointerEvents !== nextProps.pointerEvents
||
pastProps.maxLength !== nextProps.maxLength
||
pastProps.returnKeyType !== nextProps.returnKeyType
||
pastProps.placeholderTextColor !== nextProps.placeholderTextColor
||
pastProps.placeholder !== nextProps.placeholder
||
pastProps.underlineColorAndroid !== nextProps.underlineColorAndroid
||
pastProps.autoCorrect !== nextProps.autoCorrect
||
pastProps.multiline !== nextProps.multiline
||
pastProps.autoCapitalize !== nextProps.autoCapitalize
||
pastProps.keyboardType !== nextProps.keyboardType
||
pastProps.numberOfLines !== nextProps.numberOfLines
||
pastProps.defaultValue !== nextProps.defaultValue
||
pastProps.dictationSafety !== nextProps.dictationSafety
);
return shoudlUpdate;
}
componentWillUnmount() {
this.onValueChangeDelayed.cancel();
if (this.onSubmitEditingTimeout != null) {
clearTimeout(this.onSubmitEditingTimeout);
this.onSubmitEditingTimeout = null;
}
}
onValueChangeDelayed(newValue) {
if (newValue !== this.state.value) {
this.setState({
value: newValue,
});
}
}
render() {
const {
dictationSafety,
onChangeText,
onBlur,
innerTextInputRef,
onSubmitEditing,
} = this.props;
if (dictationSafety && onChangeText) {
return (
<TextInput
ref={(r) => {
if (innerTextInputRef != null) {
innerTextInputRef(r);
}
}}
{...this.props}
value={this.state.value}
onChangeText={(newValue) => {
if (this.props.onChangeText) {
this.props.onChangeText(newValue);
}
}}
onBlur={() => {
this.onValueChangeDelayed.flush();
if (onBlur) {
onBlur();
}
}}
onSubmitEditing={() => {
this.onValueChangeDelayed.flush();
if (onSubmitEditing) {
this.onSubmitEditingTimeout = setTimeout(() => {
onSubmitEditing();
}, CHANGE_TEXT_DELAY_UNTIL_DISPATCH);
}
}}
/>
);
}
return (
<TextInput
{...this.props}
/>
);
}
}
DictationSafeTextInput.defaultProps = {
dictationSafety: true,
};
DictationSafeTextInput.propTypes = {
innerTextInputRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.object,
]),
onChangeText: PropTypes.func,
onBlur: PropTypes.func,
onSubmitEditing: PropTypes.func,
dictationSafety: PropTypes.bool,
pointerEvents: PropTypes.oneOf([
'box-none',
'none',
'box-only',
'auto',
]),
autoCorrect: PropTypes.bool,
style: PropTypes.oneOfType([
PropTypes.object,
PropTypes.array,
PropTypes.number,
]),
onContentSizeChange: PropTypes.func,
editable: PropTypes.bool,
// eslint-disable-next-line
underlineColorAndroid: PropTypes.any,
value: PropTypes.string,
multiline: PropTypes.bool,
placeholder: PropTypes.string,
// eslint-disable-next-line
placeholderTextColor: PropTypes.any,
returnKeyType: PropTypes.oneOf([
// Cross-platform
'done',
'go',
'next',
'search',
'send',
// Android-only
'none',
'previous',
// iOS-only
'default',
'emergency-call',
'google',
'join',
'route',
'yahoo',
]),
autoFocus: PropTypes.bool,
blurOnSubmit: PropTypes.bool,
autoCapitalize: PropTypes.oneOf([
'none',
'sentences',
'words',
'characters',
]),
keyboardType: PropTypes.oneOf([
'default',
'email-address',
'numeric',
'phone-pad',
'number-pad',
'ascii-capable',
'numbers-and-punctuation',
'url',
'name-phone-pad',
'decimal-pad',
'twitter',
'web-search',
'visible-password',
]),
onFocus: PropTypes.func,
numberOfLines: PropTypes.number,
defaultValue: PropTypes.string,
maxLength: PropTypes.number,
};
export default DictationSafeTextInput;
从“React”导入React;
从“lodash.debounce”进口debounce;
从“道具类型”导入道具类型;
从“react native”导入{TextInput};
const CHANGE_TEXT_DELAY_直到_DISPATCH=700;
//强制执行指示安全,以便siri可以听到1个以上的单词
类DictionSafeTextInput扩展React.Component{
//
建造师(道具){
超级(道具);
这个.onValueChange延迟了=
解除绑定(this.onValueChangeDelayed.bind(this),更改文本延迟直到发送);
此.state={
价值:道具价值,
};
}
组件将接收道具(下一步){
if(this.props.value!==nextrops.value){
此.onValueChangeDelayed(nextProps.value);
}
}
shouldComponentUpdate(下一步,下一步状态){
const pastProps=this.props;
常数shoudlUpdate=(
//pastProps.value!==nextrops.value
// ||
nextState.value!==this.state.value
||
pastProps.style!==nextrops.style
||
pastProps.editable!==nextrops.editable
||
pastProps.onContentSizeChange!==nextProps.onContentSizeChange
||
pastProps.onSubmitEditing!==nextrops.onSubmitEditing
||
pastProps.onChangeText!==nextrops.onChangeText
||
pastProps.onFocus!==nextProps.onFocus
||
pastProps.onBlur!==nextrops.onBlur
||
pastProps.innerTextInputRef!==nextProps.innerTextInputRef
||
pastProps.blurOnSubmit!==nextrops.blurOnSubmit
||
pastProps.autoFocus!==nextrops.autoFocus
||
pastProps.pointerEvents!==nextProps.pointerEvents
||
pastProps.maxLength!==nextProps.maxLength
||
pastProps.returnKeyType!==nextProps.returnKeyType
||
pastProps.placeholderTextColor!==nextrops.placeholderTextColor
||
pastProps.placeholder!==nextrops.placeholder
||
pastProps.underlineColorAndroid!==nextProps.underlineColorAndroid
||
pastProps.autoCorrect!==nextrops.autoCorrect
||
pastProps.multiline!==nextrops.multiline
||
pastProps.autoCapitalize!==nextrops.autoCapitalize
||
pastProps.keyboardType!==nextProps.keyboardType
||
pastProps.numberOfLines!==nextProps.numberOfLines
||
pastProps.defaultValue!==nextProps.defaultValue
||
pastProps.DictionSafety!==nextProps.DictionSafety
);
返回并更新;
}
组件将卸载(){
此.onValueChangeDelayed.cancel();
if(this.onSubmitEditingTimeout!=null){
clearTimeout(this.onSubmitEditingTimeout);
this.onSubmitEditingTimeout=null;
}
}
onValueChangeDelayed(新值){
if(newValue!==this.state.value){
这是我的国家({
value:newValue,
});
}
}
render(){
常数{
口述安全,
一旦更改文本,
安布尔,
innerTextInputRef,
在submitediting上,
}=这是道具;
if(听写安全和更改文本(&onChangeText){
返回(
{
if(innerTextInputRef!=null){
innerTextInputRef(r);
}
}}
{……这个。道具}
value={this.state.value}
onChangeText={(newValue)=>{
if(this.props.onChangeText){
this.props.onChangeText(newValue);
}
}}
onBlur={()=>{
此.onValueChangeDelayed.flush();
if(onBlur){
onBlur();
}
}}
onSubmitEditing={()=>{
此.onValueChangeDelayed.flush();
如果(正在Submitediting){
this.onSubmitEditingTimeout=设置超时(()=>{
onSubmitEditing();
},更改\u文本\u延迟\u直到\u发送);
}
}}
/>
);
}
返回(
);
}
}
DictionSafeTextInput.defaultProps={
口述安全:正确,
};
DictionSafeTextInput.propTypes={
innerTextInputRef:PropTypes.oneOfType([
PropTypes.func,
PropTypes.object,
]),
onChangeText:PropTypes.func,
onBlur:PropTypes.func,
onSubmitEditing:PropTypes.func,
口述安全:PropTypes.bool,
pointerEvents:PropTypes.oneOf([
“无框”,
“没有”,
“仅限盒子”,
“自动”,
])