React native “反应材质”菜单在单击操作时移动

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

我有一个奇怪的位置问题:

我使用“材质”菜单组件来显示搜索结果。每个结果最多有5项。

当我点击“加载更多”按钮时,数组中又添加了5个项目,我可以滚动浏览它们。

当我开始用更多的项填充数组时,问题就开始了。菜单突然向下移动:

以下是作为父组件的搜索栏组件:

...

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个项目,但我希望保持滚动并用更多的项目填充菜单,而不是一次又一次地替换它们

你知道我怎样才能把菜单放在正确的地方吗?我不知道为什么它会这样,即使锚保持不变