How to make sticky footer with FlexBox and react

心不动则不痛 提交于 2021-02-05 08:26:50

问题


I'm using a react-native router with Flexbox. I would like to show FlatList taking the full screen and sticky footer in the end. I tried to specify flexGrow: 1 for FlatList, and flexShrink: 0 for View footer, but it doesn't work. I'm building the app in Expo and check result on iPhone.

import React, {Component} from 'react';
import {
  Text,
  View,
  FlatList,
} from 'react-native'
import {Provider} from 'react-redux'
import {NativeRouter, Route, Link} from 'react-router-native'

export default class App extends Component {
  render() {
    return <NativeRouter>
      <View style={{
        display: "flex",
        flexDirection: "column",
        padding: 10,
      }}>
        <View style={{
          display: "flex",
          flexDirection: 'row',
          justifyContent: 'space-around'
        }}>
          <Link
              to="/lobby"
              underlayColor='#f0f4f7'
              style={{
                flex: 8,
                alignItems: 'center',
                padding: 10,
              }}>
            <Text>Lobby</Text>
          </Link>
          <Link
              to="/"
              underlayColor='#f0f4f7'
              style={{
                flex: 2,
                alignItems: 'center',
                padding: 10,
              }}>
            <Text>Home</Text>
          </Link>
        </View>

        <Route exact path="/" component={Home}/>
        <Route path="/lobby" component={Lobby}/>
      </View>
    </NativeRouter>
  }
}

const Home = () => (
    <Text>
      Home
    </Text>
);


class Lobby extends Component {
  render() {
    return <View style={{
      flexGrow: 1,
      flexDirection: "column",
      // justifyContent: "space-between"
    }}>
      <FlatList
          style={{
            flexGrow: 1,
          }}
          data={[
            {key: 'Spring Game'},
            {key: 'Summer Game'},
            {key: 'Fall Game'},
            {key: 'Winter Game'},
          ]}
          renderItem={({item}) => <Text style={{
            display: "flex",
            flex: 1,
            padding: 10,
            fontSize: 18,
            height: 44,
            alignContent: "center"
          }}>{item.key}</Text>}
      />

      <View style={{
        display: "flex",
        flexDirection: "row",
        backgroundColor: "#848441",
        flexShrink: 0,
      }}>
        <Text style={{
          flex: 6,
          alignSelf: "flex-end"
        }}>Footer</Text>
      </View>
    </View>
  }
}


回答1:


First of all, good luck :) If your "stickyness logic" isn't as simple as "just stay always to the bottom" you're going to have to start listening to scrolls and resizes...

Anyway, I needed a Sticky component for my react app, and this is how it worked for me. It's react-dom so a bit different but as far as CSS is concerned it should be fine.

First, set its parent element to have position: "relative", which will allow its children to be position absolutely based on the parent. This parent element should wrap around all of your available area. So you parent View component's style is almost ok, just add flexBasis: 0 if it's not already occupying all of the available area, and position: "relative".

Set Sticky component itself (child View) to display: "block", have position: "absolute", and overflow to anything but visible. And techincally, it's sticky already. Then add bottom: 0 to your sticky, and your component should already be sticking to the bottom - now you just have to manage its width and horizontal position, with any property or tool you like.

I tried to solve this with flexbox rules only, but it seems like the best way to approach this is position="relative" and position="absolute"

You should also note that after this, the really fun part of Sticky boxes starts, because based on the actual location of your sticky you may have to add some js to handle special cases. Example: now the sticky box will cover your content, I think. Additional white space should be added to the bottom of the page so that you can actually scroll down enough to see the bottom of your content.

Additional note: I know if you combine display: "flex" and position: "relative", it's handled in a peculiar way. Not sure what exactly is different, but block and flex behave a bit differently when assigned position="relative". If you see weirdness in your layout, try adding a wrapper between your flex view and block sticky, a block/relative wrapper, to normalize behaviour.

My classes simplified, this was for a sticky sidebar:

.StickyBox {
  overflow: auto;
  position: absolute;
  height: inherit;
}

.sidebarWrapper {
  flex: 1;
  position: relative;
}


来源:https://stackoverflow.com/questions/50387589/how-to-make-sticky-footer-with-flexbox-and-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!