React native “反应材质”菜单在单击操作时移动
我有一个奇怪的位置问题: 我使用“材质”菜单组件来显示搜索结果。每个结果最多有5项。 当我点击“加载更多”按钮时,数组中又添加了5个项目,我可以滚动浏览它们。 当我开始用更多的项填充数组时,问题就开始了。菜单突然向下移动: 以下是作为父组件的搜索栏组件:React native “反应材质”菜单在单击操作时移动,react-native,material-ui,position,anchor,React Native,Material Ui,Position,Anchor,我有一个奇怪的位置问题: 我使用“材质”菜单组件来显示搜索结果。每个结果最多有5项。 当我点击“加载更多”按钮时,数组中又添加了5个项目,我可以滚动浏览它们。 当我开始用更多的项填充数组时,问题就开始了。菜单突然向下移动: 以下是作为父组件的搜索栏组件: ... const SearchBar = (props) => { const classes = useStyles(); const dispatch = useDispatch(); const
...
const SearchBar = (props) => {
const classes = useStyles();
const dispatch = useDispatch();
const [client, setClient] = useState(null)
const [db, setDB] = useState(null)
const [searchQuery, setSearchQuery] = useState('')
const [skip, setSkip] = useState(0)
const [prodList, setProdList] = useState([])
const [anchorEl, setAnchor] = useState(null)
const [menuOpen, setMenu] = useState(null)
var searchResult = useSelector(getFilteredSearch);
...
useEffect(()=>{
if(searchResult.length > 0){
if(prodList.length > 0){
setProdList([].concat.apply(prodList, searchResult))
} else {
setProdList(searchResult)
setMenu(true)
}
}
},[searchResult])
const debounced = useDebouncedCallback(
...
);
function onTextChange(val){
setSearchQuery(val.target.value)
setProdList([])
setAnchor(val.currentTarget)
debounced(val.target.value)
}
function handleLoadNext(){
var newSkip = skip + 5
setSkip(newSkip)
dispatch(loadSearch(client, db, searchQuery, newSkip))
}
function handleMenuClose(){
setMenu(false)
}
return <div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder='Search…'
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'search' }}
value={searchQuery}
onChange={e => onTextChange(e)}
onKeyUp={e => showProdList(e)}
/>
{prodList.length > 0 ?
<SearchResult
_handleLoadNext={handleLoadNext}
_handleMenuClose={handleMenuClose}
_loadNext={handleLoadNext}
_menuOpen={menuOpen}
_prodList={prodList}
_anchorEl={anchorEl}></SearchResult> :
<div></div>
}
</div>
}
export default SearchBar;
import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
// Material UI
import { Menu, MenuItem, Divider, Typography, Avatar,
Grid } from '@material-ui/core';
// React Responsive Carousel
import { Carousel } from 'react-responsive-carousel';
import '../../../../../node_modules/react-responsive-carousel/lib/styles/carousel.min.css';
// Demon Knight
import demonKnight from '../../../../assets/icons/knight_demon.png';
// React Router
import { Link } from "react-router-dom";
// Price Format
const { format } = require('number-currency-format');
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
menu: {
maxHeight: 115 * 5,
marginTop: '2%',
},
...
}));
const SearchResult = (props) => {
const classes = useStyles();
return <div>
<Menu
className={classes.menu}
anchorEl={props._anchorEl}
keepMounted
open={props._menuOpen}
onClose={props._handleMenuClose}
>
{props._prodList.map((value, i) => {
return <Link key={i} to={`/product?id=${value._id}`}>
<MenuItem button>
{value.images.length > 0 ?
<Avatar variant='square' className={classes.avatar} src={value.images[0]}/> :
<Avatar variant='square' className={classes.avatar} src={demonKnight}/>
}
<Typography className={classes.text} variant='body2' gutterBottom>{value.description.toUpperCase()}</Typography>
</MenuItem>
</Link>
})}
<Divider/>
<Grid direction='row' justify='space-evenly'>
<Grid item>
<MenuItem>BACK</MenuItem>
</Grid>
<Grid item>
<MenuItem onClick={props._loadNext}>LOAD MORE</MenuItem>
</Grid>
</Grid>
</Menu>
</div>
}
export default SearchResult;
。。。
常量搜索栏=(道具)=>{
const classes=useStyles();
const dispatch=usedpatch();
const[client,setClient]=useState(null)
const[db,setDB]=useState(null)
常量[searchQuery,setSearchQuery]=useState(“”)
常量[跳过,设置跳过]=使用状态(0)
const[prodList,setProdList]=useState([])
常量[anchorEl,setAnchor]=useState(null)
常量[menuOpen,setMenu]=useState(null)
var searchResult=useSelector(getFilteredSearch);
...
useffect(()=>{
如果(searchResult.length>0){
如果(prodList.length>0){
setProdList([].concat.apply(prodList,searchResult))
}否则{
setProdList(搜索结果)
设置菜单(真)
}
}
},[searchResult])
const debounced=useDebouncedCallback(
...
);
函数onTextChange(val){
setSearchQuery(val.target.value)
setProdList([]))
setAnchor(val.currentTarget)
取消公告(val.target.value)
}
函数handleLoadNext(){
var newSkip=skip+5
设置基普(新闻基普)
调度(loadSearch(客户端、数据库、搜索查询、新闻kip))
}
函数handleMenuClose(){
设置菜单(错误)
}
返回
onTextChange(e)}
onKeyUp={e=>showProdList(e)}
/>
{prodList.length>0?
:
}
}
导出默认搜索栏;
我在ContextChange上设置了锚,下面是菜单组件,它是一个子组件:
...
const SearchBar = (props) => {
const classes = useStyles();
const dispatch = useDispatch();
const [client, setClient] = useState(null)
const [db, setDB] = useState(null)
const [searchQuery, setSearchQuery] = useState('')
const [skip, setSkip] = useState(0)
const [prodList, setProdList] = useState([])
const [anchorEl, setAnchor] = useState(null)
const [menuOpen, setMenu] = useState(null)
var searchResult = useSelector(getFilteredSearch);
...
useEffect(()=>{
if(searchResult.length > 0){
if(prodList.length > 0){
setProdList([].concat.apply(prodList, searchResult))
} else {
setProdList(searchResult)
setMenu(true)
}
}
},[searchResult])
const debounced = useDebouncedCallback(
...
);
function onTextChange(val){
setSearchQuery(val.target.value)
setProdList([])
setAnchor(val.currentTarget)
debounced(val.target.value)
}
function handleLoadNext(){
var newSkip = skip + 5
setSkip(newSkip)
dispatch(loadSearch(client, db, searchQuery, newSkip))
}
function handleMenuClose(){
setMenu(false)
}
return <div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder='Search…'
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'search' }}
value={searchQuery}
onChange={e => onTextChange(e)}
onKeyUp={e => showProdList(e)}
/>
{prodList.length > 0 ?
<SearchResult
_handleLoadNext={handleLoadNext}
_handleMenuClose={handleMenuClose}
_loadNext={handleLoadNext}
_menuOpen={menuOpen}
_prodList={prodList}
_anchorEl={anchorEl}></SearchResult> :
<div></div>
}
</div>
}
export default SearchBar;
import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
// Material UI
import { Menu, MenuItem, Divider, Typography, Avatar,
Grid } from '@material-ui/core';
// React Responsive Carousel
import { Carousel } from 'react-responsive-carousel';
import '../../../../../node_modules/react-responsive-carousel/lib/styles/carousel.min.css';
// Demon Knight
import demonKnight from '../../../../assets/icons/knight_demon.png';
// React Router
import { Link } from "react-router-dom";
// Price Format
const { format } = require('number-currency-format');
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
menu: {
maxHeight: 115 * 5,
marginTop: '2%',
},
...
}));
const SearchResult = (props) => {
const classes = useStyles();
return <div>
<Menu
className={classes.menu}
anchorEl={props._anchorEl}
keepMounted
open={props._menuOpen}
onClose={props._handleMenuClose}
>
{props._prodList.map((value, i) => {
return <Link key={i} to={`/product?id=${value._id}`}>
<MenuItem button>
{value.images.length > 0 ?
<Avatar variant='square' className={classes.avatar} src={value.images[0]}/> :
<Avatar variant='square' className={classes.avatar} src={demonKnight}/>
}
<Typography className={classes.text} variant='body2' gutterBottom>{value.description.toUpperCase()}</Typography>
</MenuItem>
</Link>
})}
<Divider/>
<Grid direction='row' justify='space-evenly'>
<Grid item>
<MenuItem>BACK</MenuItem>
</Grid>
<Grid item>
<MenuItem onClick={props._loadNext}>LOAD MORE</MenuItem>
</Grid>
</Grid>
</Menu>
</div>
}
export default SearchResult;
import React,{useffect,useState}来自“React”;
从'@material ui/core/styles'导入{makeStyles};
//材料界面
导入{菜单、菜单项、分隔符、排版、化身、,
网格}来自“@material ui/core”;
//反应式旋转木马
从“反应响应旋转木马”导入{Carousel};
导入“../../../../../node_modules/react responsive carousel/lib/styles/carousel.min.css”;
//恶魔骑士
从“../../../assets/icons/knight_demon.png”导入demonKnight;
//反应路由器
从“react router dom”导入{Link};
//价格格式
const{format}=require('number-currency-format');
const useStyles=makeStyles((主题)=>({
根目录:{
宽度:“100%”,
最大宽度:360,
背景色:theme.palete.background.paper,
},
菜单:{
最大高度:115*5,
玛金托普:“2%,
},
...
}));
const SearchResult=(道具)=>{
const classes=useStyles();
返回
{props.\u prodList.map((值,i)=>{
返回
{value.images.length>0?
:
}
{value.description.toUpperCase()}
})}
返回
加载更多
}
导出默认搜索结果;
我试着在maxHeight中使用样式,在单击LOAD MORE时重置锚定,我试着禁用自动对焦,但什么都不起作用。
唯一的解决办法是用新的5个项目替换5个项目,跳过整个滚动机制,并有一个返回按钮,可以返回以前的5个项目,但我希望保持滚动并用更多的项目填充菜单,而不是一次又一次地替换它们
你知道我怎样才能把菜单放在正确的地方吗?我不知道为什么它会这样,即使锚保持不变