Как я могу структурировать эту реализацию React Native Section List - PullRequest
4 голосов
/ 02 апреля 2019

Итак, я хочу использовать список разделов RN неортодоксальным способом.

Я хочу, чтобы список разделов выдавал рендеринг компоненту, поскольку рендеринг не будет очень равномерным.

Я хочу использовать список разделов, чтобы при прокрутке вы все равно могли видеть заголовки.

Я создал компонент, который принимает дочерние элементы и отображает их в списке разделов следующим образом:

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 для этого является излишним (но оно делает показ заголовков более приятным), поэтому открыты и для альтернатив.

Ответы [ 2 ]

4 голосов
/ 05 апреля 2019

Вы можете сделать это, используя 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 с абсолютной позицией, и вы можете скрыть это, когда все вещи отображаются правильно.

0 голосов
/ 10 апреля 2019

Вот альтернатива, о которой я думаю после полезного совета @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, он не будет отображаться, но он все равно будет визуализирован и скажет, что в более поздний момент времени этот раздел изменится и внезапно отобразит что-тотеперь будет отображаться в списке разделов.

Хотите узнать какие-либо отзывы об этом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...