没有CSS的反应响应式布局

m1g*_*u3l 30 javascript layout reactjs responsive

我想知道在React app中实现布局的最佳方法是什么.

基本

假设我们想要在简单的网格中布置4个组件.最基本的方式是这样的.

<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
  <A color="red" x={0} y={0} width={width/2} height={height/2} />
  <B color="blue" x={width/2} y={0} width={width/2} height={height/2} />
  <B color="green" x={0} y={height/2} width={width/2} height={height/2} />
  <A color="yellow" x={width/2} y={height/2} width={width/2} height={height/2} />
</svg>
Run Code Online (Sandbox Code Playgroud)

http://codepen.io/anon/pen/OWOXvV?editors=0010

它可以正常工作,但键入显式大小值容易出错并且不适合开发人员.如果我们可以使用百分比值(0 - 1),该怎么办?

简单的容器

const Container = ({x, y, width, height, children}) => {
  return (
    <g transform={`translate(${x}, ${y})`}>
      {React.Children.map(children, (child) => React.cloneElement(child, { // this creates a copy
        x: child.props.x * width,
        y: child.props.y * height,
        width: child.props.width * width,
        height: child.props.height * height
      }))}
    </g>
  );
};

 <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
  <Container width={width} height={height}>{/* one root container is given real pixel size */}
    <Container width={1/2}>{/* it's children recursively use 0-1 coordinates */}
      <A color="red" height={1/2} />
      <B color="green" y={1/2} height={1/2} />
    </Container>
    <Container x={1/2} width={1/2}>
      <B color="blue" height={1/2} />
      <A color="yellow" y={1/2} height={1/2} />
    </Container>
  </Container>
</svg>
Run Code Online (Sandbox Code Playgroud)

http://codepen.io/anon/pen/PWEmVd?editors=0010

在这种情况下,我们将允许Container组件将其子项相对值映射到实际像素值.它更容易使用.

布局容器

另一个步骤是创建布局容器,fe HContainer只是水平放置它的子.

const HContainer = ({ x, y, width, height, children }) => {
  const c = React.Children.toArray(children);
  const ratio = width / c.reduce((sum, child) => (sum + child.props.width), 0);
  return (
    <g transform={`translate(${x}, ${y})`}>
      {c.reduce((result, child) => {
        const width = child.props.width * ratio;
        result.children.push(React.cloneElement(child, { // this creates a copy
          x: result.x,
          y: 0,
          width,
          height
        }));
        result.x += width;
        return result;
      }, { x: 0, children: [] }).children}
    </g>
  );
};

<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
  <HContainer width={width} height={height}>{/* one root container is given real pixel size */}
    <Container width={1/4}>{/* it's children recursively use 0-1 coordinates */}
      <A color="red" height={1/2} />
      <B color="green" y={1/2} height={1/2} />
    </Container>
    <VContainer width={3/4}>
      <B color="blue" />
      <A color="yellow" />
      <HContainer height={1/2}>
        <B color="pink" />
        <A color="violet" width={3} />
        <B color="#333" />
      </HContainer>
    </VContainer>
  </HContainer>
</svg>
Run Code Online (Sandbox Code Playgroud)

http://codepen.io/anon/pen/pRpwBe?editors=0010

响应组件

假设我们希望在宽度或高度低于某个值时删除某些组件.您可能会使用这样的条件渲染.

const MinWidth = ({ children, width, minWidth, ... others }) => {
  return minWidth > width ? null : <Container width={width} {... others }>{ children }</Container>;
};

<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
  <HContainer width={width} height={height}>{/* one root container is given real pixel size */}
    <Container width={1/4}>{/* it's children recursively use 0-1 coordinates */}
      <A color="red" height={1/2} />
      <B color="green" y={1/2} height={1/2} />
    </Container>
    <VContainer width={3/4}>
      <B color="blue" />
      <MinHeight height={1} minHeight={80}>
        <A color="yellow" />
      </MinHeight>
      <HContainer height={1/2}>
        <B color="pink" />
        <A color="violet" width={3} />
        <MinWidth width={1} minWidth={60}>
          <B color="#333" />
        </MinWidth>
      </HContainer>
    </VContainer>
  </HContainer>
</svg>
Run Code Online (Sandbox Code Playgroud)

http://codepen.io/anon/pen/dNJZGd?editors=0010

但这留下了空闲空间,其中跳过了组件.布局容器应该能够扩展渲染的组件以填充可用空间.

响应式布局

这是棘手的部分.我看不到其他任何方式来查看组件是否将呈现,而是实例化并呈现它(以及它的子项).然后,如果我在可用空间中放置3个子组件并发现第4个不应该渲染,我将不得不重新渲染之前的3.感觉就像打破了React流.

有没有人有任何想法?

J. *_*ens 5

在内联样式中使用flexbox.您已经在代码外观中使用内联样式.这是一些帮助