5

所以我想以一种非正统的方式使用 RN Section list。

我希望部分列表将渲染传递给组件,因为渲染不会很统一。

我想使用部分列表,以便在滚动时仍然可以看到标题。

我制作了一个组件,它接收孩子并将它们呈现在一个部分列表中,如下所示:

class SomeSectionList extends Component {

    render() {
        let sections = React.Children.map(this.props.children, (Child, index) => {
            return {title: Child.type.title, data: [''], renderItem: () => Child, index }
    });

        return (
            <SectionList

                renderSectionHeader={({section}) => {
                    return <Text style={{ fontWeight: "bold" }}>{section.title}</Text>
        }}
                sections={sections}
                keyExtractor={(item, index) => item + index}
            />
        );
    }
}

用法如下:

                <SomeSectionList>
                    <Comp1 />
                    <Comp2 />
                </SomeSectionList>

但是,我的问题是。假设在这种情况下 Comp1 不会从它的组件中渲染任何东西,我希望能够从部分列表中隐藏它的部分。

组件怎么会SomeSectionList知道它没有渲染任何东西或没有数据来渲染任何东西,所以它可以隐藏它的部分和标题?

任何建议都会很棒。我觉得为此使用 SectionList 有点矫枉过正(但它可以更好地显示标题),因此也对替代方案持开放态度。

4

2 回答 2

3

您可以onLayout使用View.

通过它我们可以获得渲染组件的高度。如果为 0,则表示其中没有渲染任何内容,否则它包含一些数据。

看这个关于零食的工作示例

export default class App extends React.Component {
  render() {
    return (
      <SomeSectionList>
        <Comp1 />
        <Comp2 />
        <Comp1 />
        <Comp2 />
        <Comp1 />
      </SomeSectionList>
    );
  }
}

class Comp1 extends React.Component {
  render() {
    return (
      <View>
        <Text>Comp11</Text>
      </View>
    );
  }
}

class Comp2 extends React.Component {
  render() {
    return null;
  }
}

class SomeSectionList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      children: this.props.children,
    };
  }
  onLayout = (event, index) => {
    if (event.nativeEvent.layout.height <= 0) {
      let oldProps = this.state.children;
      oldProps.splice(index, 1);
      this.setState({ children: oldProps });
    }
  };
  render() {
    let sections = React.Children.map(this.state.children, (Child, index) => {
      return {
        title: Child.type.title,
        data: [''],
        renderItem: () => (
          <View onLayout={event => this.onLayout(event, index)}>
            {this.state.children[index]}
          </View>
        ),
        index,
      };
    });

    return (
      <SectionList
        renderSectionHeader={({ section }) => {
          return <Text style={{ fontWeight: 'bold' }}>{section.title}</Text>;
        }}
        sections={sections}
        keyExtractor={(item, index) => item + index}
      />
    );
  }
}

在这里,首先,我们已经分配this.props.children到状态。然后在onLayout方法中,我们正在检查当前索引子项的高度是否为 0。如果是,则将其从子数组中删除。

您会清楚地看到一些视图正在删除。对于这件事,我们在一个场景中所做的就是放置一个加载器,它SectionList用绝对位置覆盖整个区域,当所有东西都正确渲染时,你可以隐藏它。

于 2019-04-05T05:32:57.827 回答
0

这是我在@JaydeepGalani 的有用建议后正在考虑的替代方案!

class SomeSectionList extends Component {
  constructor(props) {
    super(props)
    this.state = {
            hiddenChildren: {}
    }
  }


  onLayout = (event, index) => {
    if (event.nativeEvent.layout.height <= 0) {
            const hiddenChildren = this.state.hiddenChildren
            hiddenChildren[index] = true
            this.setState({
                hiddenChildren
            })
    } else {

            const hiddenChildren = this.state.hiddenChildren
            delete hiddenChildren[index]
            this.setState({
                hiddenChildren
            })
    }
  }

    render() {
        let sections = React.Children.map(this.props.children, (Child, index) => {
            return {
                title: Child.type.title, 
                index,
        data: [''], 
        renderItem: () => (
          <View onLayout={event => this.onLayout(event, index)}>
            {this.state.children[index]}
          </View>
      )}
    });

        return (
            <SectionList

                renderSectionHeader={({section}) => {
                    const index = section.index
                    if (this.state.hiddenChildren[index]) return 

                    return <Text style={{ fontWeight: "bold" }}>{section.title}</Text>
        }}
                sections={sections}
                keyExtractor={(item, index) => item + index}
            />
        );
    }
}

由于在第一个实现中,一旦该部分被删除,由于 onLayouts 不会被触发,因此很难将其恢复。在此我们仍然在技术上“渲染”该部分,但隐藏标题并且由于该部分的高度为 0 它不会显示,但它仍然被渲染并在稍后的时间点说该部分更改并突然渲染它现在将显示在部分列表中。

对有关此问题的任何反馈感到好奇?

于 2019-04-10T17:41:57.827 回答