首页 > 解决方案 > React - 子组件的自定义布局

问题描述

我正在编写一个小部件库,我想让用户灵活地使用他们自己的布局。例如,我有一个Tracker小部件负责跟踪一个点的当前位置。这里是使用的概述Tracker

<Tracker initialPos={[0,0]}> //<-- holds state of current position
    <TrackerPlot option={1} />
    <TrackerPlot option={2} />
    <TrackerPlot option={3} />
    ...
    <TrackerPlot option={n} />
    <TrackerControls />
</Tracker>

这很好,但我想为库的用户提供额外的灵活性来添加自定义布局,以便他们可以将 Tracker 组件放置在他们喜欢的位置。就像是:

<Tracker initialPos={[0,0]}>
  <div class="USER-DEFINED-LAYOUT-PLOTS">
    <TrackerPlot val={1} />
    <TrackerPlot val={2} />
    <TrackerPlot val={3} />
    ...
    <TrackerPlot val={n} />
  </div>
  <div class="USER-DEFINED-LAYOUT-CONTROLS">
    <TrackerControl />
  </div>
</Tracker>

问题是我一直在使用儿童道具如下:

function Tracker(props){
  const [pos, setPos] = useState(props.initialPosition);
  const children = React.Children.map(props.children, child=>{
   return React.cloneElement(child, {
      pos:pos
     });
  });
  return {children};
}

如果我可以灵活地添加周围环境<div>,那么上面访问子项的代码就会中断。是否有模式/工具/设计允许用户使用子组件定义自己的布局

标签: reactjs

解决方案


这是context api的经典用法,您的父母将成为提供者,您的孩子将成为消费者。

// PosContext.jsx
export const PosContext = React.createContext({
  pos: initialPosition
});


//Tracker.jsx
import {PosContext} from './PosContext';

export const Tracker = ({ initialPos, children }) => (
  <PosContext.Provider value={{ pos: initialPos }}>{children}</PosContext.Provider>
);


// TrackerPlot.jsx
import { PosContext } from './PosContext';

export const TrackerPlot = props => (
  <PosContext.Consumer>{({ pos }) => <div>{pos}</div>}</PosContext.Consumer>
);


推荐阅读