我正在使用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 />
。上面的方法有效,但是它正在创建3个SignUpForm
实例...如果您调整浏览器的大小并碰到一个断点,则由于SignUpForm
的新实例加载,您已经填写的任何表单数据都会丢失。如何将其更改为使用媒体查询,但只使用<SignUpForm />
的一个实例。 最佳答案
嗯我对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';
}