我正在使用react-responsive
来获取媒体查询,我希望在屏幕大小之间共享一个组件状态,但使用不同的包装器。
示例:
import MediaQuery from 'react-responsive';
import ReactSwipe from 'react-swipe';
const Desktop = props => <MediaQuery {...props} minWidth={992} />;
const Tablet = props => <MediaQuery {...props} minWidth={768} maxWidth={991} />;
const Mobile = props => <MediaQuery {...props} maxWidth={767} />;
export class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Desktop>
<SignUpForm />
</Desktop>
<Tablet>
<SignUpForm />
</Tablet>
<Mobile>
<ReactSwipe>
<SignUpForm />
</ReactSwipe>
</Mobile>
</div>
);
}
}
在此示例中,我想使用另一个组件<ReactSwipe>
来封装<SignUpForm />
。上面的工作,但它创建了SignUpForm
的3个实例...如果您调整浏览器的大小并点击断点,您填写的任何表单数据都将在SignUpForm
的新实例加载时丢失。如何更改此选项以使用媒体查询,但只有<SignUpForm />
的一个实例。
答案 0 :(得分:2)
嗯。我不熟悉MediaQuery,但我的做法不一样。我会编写/找到一个识别当前平台的函数,然后根据它进行切换:
const wrappers = {
desktop: Desktop,
tablet: Tablet,
mobile: Mobile, // I'd have this wrapper do the ReactSwipe thing
};
export function App() {
// returns a string that is one of: 'desktop', 'tablet', 'mobile'
const platform = findPlatform();
const Wrapper = wrappers[platform];
return (
<Wrapper>
<SignUpForm />
</Wrapper>
);
}
另外,正如您将在上面看到的那样,当函数执行时,我从不使用ES6类。我尝试尽可能不经常使用类。这是个人偏好,但我发现它鼓励我编写更简单的代码。
正如所提出的,这是findPlatform
的可能(未经测试)实现。我将它放在自己的模块中,因此在测试过程中可以更容易地进行模拟。
function findPlatform() {
const minTabletSize = 768; // Make this whatever you think is best
if (!(/Mobi/.test(navigator.userAgent))) {
return 'desktop';
}
if (window.outerHeight > minTabletSize || window.outerWidth > minTabletSize) {
return 'tablet';
}
return 'mobile';
}