在自定义组件中反应原生访问 refs
Posted
技术标签:
【中文标题】在自定义组件中反应原生访问 refs【英文标题】:React native accessing refs in a custom component 【发布时间】:2016-08-11 12:04:24 【问题描述】:我有一个自定义的 TextInput。当我编辑第一个TextInput
并点击键盘上的“下一步”时,我希望它关注第二个TextInput
。我之前在 Stack Overflow 中搜索过,看来我可以使用 ref
进行搜索。但是我不确定如何使用自定义TextInput
来做到这一点。
这是我的基本 CustomTextInput 代码:
let CustomTextInput = React.createClass(
propTypes:
refName: React.PropTypes.string,
returnKeyType: React.PropTypes.string,
onSubmitEditing: React.PropTypes.func
,
getDefaultProps: function()
return
refName: "",
returnKeyType: "default",
onSubmitEditing: () =>
,
render: function()
return(
<View>
<TextInput
ref=this.props.refName
returnKeyType=this.props.returnKeyType
onSubmitEditing=this.props.onSubmitEditing
/>
</View>
)
);
module.exports = CustomTextInput
这是我的父类调用它:
let MyParent = React.createClass(
render: function()
return(
<View>
<CustomTextInput
refName='firstNameInput',
returnKeyType='next'
onSubmitEditing=(event) =>
this.refs.lastNameInput.focus();
/>
<CustomTextInput
refName='lastNameInput'
/>
</View>
)
);
现在,当我按下键盘上的Next
,选择firstName
后,出现异常:
undefined 不是一个对象(评估 '_this2.refs.lastNameInput.focus')
我不确定我在那里做错了什么。感谢任何帮助。 :)
【问题讨论】:
【参考方案1】:让我们从 CustomTextInput 组件开始。
export default class CustomTextInput extends Component
componentDidMount()
if (this.props.onRef != null)
this.props.onRef(this)
onSubmitEditing()
this.props.onSubmitEditing();
focus()
this.textInput.focus()
render()
return (
<View>
<View style=this.state.isFocused ? styles.onFocusedStyle : styles.onBlurStyle>
<TextInput
ref=input => this.textInput = input
onSubmitEditing=this.onSubmitEditing.bind(this)
/>
</View>
<Text style=styles.errorMessageField>this.state.errorStatus && this.props.errorMessage</Text>
</View>
);
这里我有一个示例 customTextInput。这里需要注意的重要事项是 render 方法中 TextInput 视图中的 componentDidMount()、focus() 方法和 ref 属性。
componentDidMount() 方法将整个 CustomTextInput 组件的 ref 传递给它的父组件。通过该引用,我们将从父组件调用 CustomTextInput 组件的 focus 方法。
这里的focus()方法通过使用CustomTextInput组件内部TextInput组件的ref将textInput聚焦在CustomTextInput组件内部。
TextInput 的 ref 属性存储了 TextInput 的引用。该引用由 focus() 方法使用。
现在让我们看看父组件
export default class ParentComponent extends Component
constructor(props)
super(props);
this.focusNextField = this.focusNextField.bind(this);
this.inputs = ;
focusNextField(id)
this.inputs[id].focus();
render()
return (
<ScrollView
contentContainerStyle=paddingBottom:100
keyboardDismissMode='on-drag'
scrollToTop=true>
<View>
<View style=marginTop: 10>
<CustomTextInput
onRef=(ref) =>
this.inputs['projectName'] = ref;
onSubmitEditing=() =>
this.focusNextField('projectDescription');
/>
</View>
<View style=marginTop: 10>
<CustomTextInput
onRef=(ref) =>
this.inputs['projectDescription'] = ref;
onSubmitEditing=() =>
this.focusNextField('subDivision');
/>
</View>
<View style=marginTop: 10>
<CustomTextInput
onRef=(ref) =>
this.inputs['subDivision'] = ref;
onSubmitEditing=() =>
this.focusNextField('plan');
/>
</View>
<View style=marginTop: 10>
<CustomTextInput
onRef=(ref) =>
this.inputs['plan'] = ref;
</View>
</View>
</ScrollView>
);
在父组件中,我们使用 onRef 属性存储每个 CustomTextInput 的 ref,当按下键盘的提交按钮时,我们调用下一个 CustomTextInput 的 focus 方法,CustomTextInput 的 focus 方法将 TextInput 聚焦在子组件中。
【讨论】:
非常感谢 - 我一直在努力解决这个问题,你是第一个解释清楚的人 乐于助人:) 太棒了!这对我有很大帮助!谢谢 如何在功能组件中做到这一点? @Supto @ShubhamKumar 请仔细阅读此文档,它将帮助您了解更多。如果可能的话,我会尝试更新答案。 reactjs.org/docs/refs-and-the-dom.html【参考方案2】:这是一个对我有用的解决方案——基本上你在你的自定义组件中做了一个引用,你可以从你的父组件中的引用中访问它:
let CustomTextInput = React.createClass(
propTypes:
refName: React.PropTypes.string,
returnKeyType: React.PropTypes.string,
onSubmitEditing: React.PropTypes.func
,
getDefaultProps: function()
return
refName: "",
returnKeyType: "default",
onSubmitEditing: () =>
,
render: function()
return(
<View>
<TextInput
ref="input"
returnKeyType=this.props.returnKeyType
onSubmitEditing=this.props.onSubmitEditing
/>
</View>
)
);
module.exports = CustomTextInput
并且在父组件中:
let MyParent = React.createClass(
render: function()
return(
<View>
<CustomTextInput
refName='firstNameInput',
returnKeyType='next'
onSubmitEditing=(event) =>
this.lastNameInput.refs.input.focus();
/>
<CustomTextInput
refName=ref => this.lastNameInput = ref
/>
</View>
)
);
【讨论】:
【参考方案3】:let CustomTextInput = React.createClass(
componentDidMount()
// this is to check if a refName prop is FUNCTION;
if (typeof this.props.rex === "function")
this.props.refName(this.refs.inp);
render: function()
return(
<View>
<TextInput ref="inp"/>
</View>
)
);
let MyParent = React.createClass(
render: function()
return (
<View>
<CustomTextInput
refName= (firstNameInput) => this.firstNameInput = firstNameInput
/>
</View>
)
);
【讨论】:
【参考方案4】:试试这个:
let AwesomeProject = React.createClass(
onSubmitEditing:function(event)
if (this.myTextInput !== null)
this.myTextInput.focus();
,
render()
return(
<View>
<CustomTextInput
returnKeyType='next'
onSubmitEditing=this.onSubmitEditing
/>
<CustomTextInput
refName=(ref) => this.myTextInput = ref
/>
</View>
)
);
【讨论】:
以上是关于在自定义组件中反应原生访问 refs的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift 反应原生自定义 UI 组件:如何在事件中访问 reactTag
在自定义组件中调用 useState Hook 时反应本机 TextInput ReRenders