You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Ref数组更新后Dropdown组件未重新渲染问题

问题:React Native动态下拉框数据不更新

我实现了一个基于文本输入的动态下拉框,用于展示匹配度最高的字符串。使用useRef存储文本输入值以及API返回的数组,控制台中能看到数组值每次都会变化,但将ref数组传递给Dropdown组件的props后,组件内部的值却没有更新。希望每次按键输入时,新值都能传递到下拉框中。


核心原因

useRef的变更不会触发组件重渲染。你用arrRef存储下拉数据,更新ref.current后,StartScreen组件不会重新渲染,Dropdown自然无法获取到最新数据。

修复方案

  • 用useState替代useRef存储下拉数据:状态变更会触发组件重渲染,确保Dropdown能获取到最新数据
  • 简化数据处理逻辑:直接将API返回的数组赋值给状态,无需额外的addToArr函数
  • 调整Dropdown组件的props类型:接收普通数组而非Ref对象,简化组件内部逻辑

修改后的StartScreen代码

import React, { useState, useRef } from 'react';
import styled ,{css} from 'styled-components/native';
import { Container, screenWidth } from '../utils/shared';
import { StackNavigationProp } from '@react-navigation/stack';
import { StackParamList } from '../navigation/StackNavigation';
import { useNavigation } from '@react-navigation/native';
import { getCityByName } from '../utils/cityApi';
import mapPng from "../assets/map.png";

//Components
import BackArrowButton from '../components/Buttons/BackArrowButton';
import Search from '../components/Inputs/Search';
import RegularText from '../components/Text/RegularText';
import TextButton from '../components/Buttons/TextButton';
import RegularButton from '../components/Buttons/RegularButton';
import Dropdown from '../components/Sliders/Dropdown';

const StartScreen: React.FC = () => {
    // 输入值用useRef存储(无需触发重渲染,合理)
    const nameRef = useRef<string>("");
    const updateNameRef = (name: string)=>{
      nameRef.current = name;
      fetchCities();
    };

    // 改用useState存储下拉数据,状态变更触发重渲染
    const [dropdownArr, setDropdownArr] = useState<string[]>([]);

    type stackProps = StackNavigationProp<StackParamList ,"Start">;
    const navigation = useNavigation<stackProps>();

    const goBack = () =>{
      navigation.navigate("Welcome");
    };

    const skipPress = () =>{
      navigation.navigate("Home")
    };

    const StyledImage = styled.Image`
      width: 60%;
      height: 200px;
      object-fit:cover;
    `;

    const StyledView = styled.View`
    justify-content:space-between;
    align-items: center;
    height: 400px;
    display: flex;
    width: ${screenWidth}px;
    `;

    const customSpace = css`
      margin-top: 21px;
    `;

    // 简化API数据处理逻辑
    const fetchCities = async () => {
      if (nameRef.current !== "") {
        const arr = await getCityByName(nameRef.current, 0, 5);
        setDropdownArr(arr || []);
      } else {
        setDropdownArr([]);
      }
    };

  return (
    <Container>
      <BackArrowButton onPress={goBack}/>

    <StyledView>
      <StyledImage source={mapPng} />
      <RegularText str='Please enter your location' customCss={customSpace}/>
      <Search placeHolder='City...' updateNameRef={updateNameRef}/>

      {/* 直接传递普通数组给Dropdown */}
      <Dropdown arr={dropdownArr}/>
      
      <RegularButton ButtonText='Enter' onPress={skipPress} customCss={customSpace}/>
      <TextButton str='skip' onPress={skipPress} size={17}  customCss={customSpace}/>
    </StyledView>

    </Container>
  );
}

export default StartScreen;

修改后的Dropdown组件代码

import React from 'react';
import styled from 'styled-components/native';
import { colorPalette } from '../../utils/colors';
import { screenWidth } from '../../utils/shared';

//Components
import NameCard from '../Cards/NameCard';
import { FlatList } from 'react-native';

// 调整props类型为普通字符串数组
interface DropdownProps {
    arr: string[];
}

const StyledView = styled.View`
    max-height: 90px;
    min-height: 0px;
    width: ${screenWidth*0.7}px;
    background: ${colorPalette.white};
    border-radius: 0px 0px 7px 7px;
    position: relative;
    padding-top: 7px;
`;

const BorderInside = styled.View`
    position: absolute;
    top: 1px;
    left: 2.5%;
    width: 95%;
    height: calc(100% - 0.5px);
    border: 0.2px solid grey;
`;


const Dropdown: React.FC<DropdownProps> = (props) => {
    return (
    <StyledView>
        <BorderInside />
        
        <FlatList
        data={props.arr}
        keyExtractor={(item) => item}
        renderItem={({ item }) => (
            <NameCard key={item} str={item} />
            )}
        />
    </StyledView>
    );
}

export default Dropdown;

内容的提问来源于stack exchange,提问作者Benjamin Hanonove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:20:09