我正在尝试在React Native(使用Coffeescript)中切换动态创建的组件的显示。创建的组件符合JSON对象的结构,并且每个组件都具有ref
属性,具有相应的id
,因此我可以访问特定组件,如下所示:this.refs[ id ]
我有以下功能来更改组件的显示
changeDisplay: ( id ) ->
this.refs[ id ].setNativeProps( {
display: 'flex'
} );
当我想要更改初始显示时,此功能正常,但我想在none
和flex
之间切换显示(基于当前状态)。
因为我不知道在正手上呈现了多少项目,所以我不能(或不知道如何)为它们定义状态。
我尝试了以下操作,但在使用setNativeProps()
changeDisplay: ( id ) ->
if this.refs[ id ].props.style.display is 'none'
this.refs[ id ].setNativeProps( {
display: 'flex'
} );
else
this.refs[ id ].setNativeProps( {
display: 'none'
} );
最初this.refs[ id ].props.style.display
返回组件在加载视图时所处的状态(= none
),但是在我运行上面的函数之后,显示状态在视觉上被更改(组件显示),但this.refs[ id ].props.style.display
仍会返回初始状态none
为什么呢?
修改
下面是我的(剥离的)组件(根据要求)。我想切换某个项目中子任务的显示。因此,如果我点击项目Project 1
,我想切换任务的显示状态1& 2。
import React from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
ScrollView
} from 'react-native';
import {
Icon,
} from 'react-native-elements';
class ListTasks extends React.Component
constructor: ( props ) ->
super props
this.data =
list: [
{
id: 1
name: 'Project 1'
type: 'project'
parent: null
},{
id: 2
parent: 1
name: 'Task 1'
type: 'task'
},{
id: 3
parent: 1
name: 'Task 2'
type: 'task'
},{
id: 4
name: 'Project 2'
type: 'project'
parent: null
},{
id: 5
parent: 4
name: 'Task 3'
type: 'task'
},{
id: 6
parent: 4
name: 'Task 4'
type: 'task'
}
]
toggleDisplay: ( id ) ->
if this.refs[ id ].props.style.display is v[ 0 ]
this.refs[ id ].setNativeProps( {
display: 'flex'
} );
else
this.refs[ id ].setNativeProps( {
display: 'none'
} );
renderList: ( data ) ->
<View>
<View>
<TouchableOpacity onPress={() => this.toggleDisplay( data.id )}>
<Text>{data.name}</Text>
</TouchableOpacity>
</View>
<View ref={data.id} style={display: 'none'}>
{ this.renderTask cor for cor in this.data.list when cor.parent is data.id }
</View>
</View>
renderTask: ( data ) ->
<View>
<Text>{data.name}</Text>
</View>
render: ->
<View>
<ScrollView style={height:'100%'}>
{ this.data.list.map( ( data ) =>
if data.type == 'project'
this.renderList( data )
) }
</ScrollView>
</View>
export default ListTasks
答案 0 :(得分:0)
您的数据结构不是非常适合存储明显具有2D截面关系的数据。我在下面修改了数据结构。
DOM操作也不是React方式。相反,我们使用状态来管理元素的可见性和属性。
分段可折叠列表的工作示例:
import React from 'react';
import { Text, TouchableOpacity, SectionList } from 'react-native';
const data = [
{
id: 1,
name: 'Project 1',
type: 'project',
data: [
{
id: 2,
name: 'Task 1',
type: 'task',
},
{
id: 3,
name: 'Task 2',
type: 'task',
},
],
},
{
id: 4,
name: 'Project 2',
type: 'project',
data: [
{
id: 5,
name: 'Task 3',
type: 'task',
},
{
id: 6,
name: 'Task 4',
type: 'task',
},
],
},
];
class ListTasks extends React.Component {
state = {
list: data,
show: {},
};
render() {
// SectionList is used instead of ScrollView as it has better performance
return (
<SectionList
style={{ marginTop: 50 }}
sections={this.state.list}
renderItem={({ item, section }) =>
// render null if show state for the section is falsy
(this.state.show[section.id] ? <Text style={{ padding: 10 }}>{item.name}</Text> : null)
}
renderSectionHeader={({ section }) => (
<TouchableOpacity
style={{ paddingVertical: 10, margin: 10, backgroundColor: 'grey' }}
onPress={() =>
this.setState((prevState) => ({
show: {
...prevState.show,
// toggle the show state for the seciton
[section.id]: !prevState.show[section.id],
},
}))
}
>
<Text>{section.name}</Text>
</TouchableOpacity>
)}
keyExtractor={(item) => item.id}
/>
);
}
}
export default ListTasks;