Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.6k views
in Technique[技术] by (71.8m points)

javascript - Custom React Native Picker Select Component automatically selects before pressing done

Whenever I select a item from my react native picker select component it automatically selects the value before hitting done. As soon as your finger lifts of the picker it selects and closes.

I have exhausted everything I can think of to fix, I must be overlooking something obvious. I feel like it must have something to do with the selectedValue hook since when I pass as props it no longer auto selects.

When I try to pass the selectedValue as props I run into the error Warning: Cannot update a component from inside the function body of a different component. Since I am updating each dropdown based on the selection of any other.

Here is my custom dropdown component.

I appreciate any help on this in advance.

const useDropdown = (label, defaultState, options) => {
 const [selectedValue, setSelectedValue] = useState(defaultState);

 const DropdownMaker = props => (
   <View style={[DefaultStyles.formBox, props.style]}>
     <RNPickerSelect
       style={{
         inputIOS: [DefaultStyles.bodyTextBlack],
         inputAndroid: [DefaultStyles.bodyTextBlack],
         placeholder: {
           fontSize: hp("2%"),
           textAlign: "center",
           fontFamily: "Raleway-Semibold",
         },
       }}
       useNativeAndroidPickerStyle={false}
       value={selectedValue}
       placeholder={{ label }}
       disabled={props.disabled}
       onValueChange={props.onValueChange}
       items={options.map(x => ({ label: x, value: x }))}
     />
   </View>
 );
 return [selectedValue, DropdownMaker, setSelectedValue];
};

export default useDropdown;

Here is how it is passed to parent component.

const SearchScreen = props => {
  const songData = useSelector(state => state.filter.songData);
  const filteredSongs = useSelector(state => state.filter.filteredSongs);
  const isAudioPlaying = useSelector(state => state.player.isAudioPlaying);
  const [genres, setGenres] = useState([]);
  const [selectedGenre, GenreDropdown, setSelectedGenre] = useDropdown(
    "Genre",
    null,
    genres
  );
  const [moods, setMoods] = useState([]);
  const [selectedMood, MoodDropdown, setSelectedMood] = useDropdown(
    "Mood",
    null,
    moods
  );
  const [styleToggle, setStyleToggle] = useState();
  const [dropdownStyle, setDropdownStyle] = useState();
  const [dropdownDisabled, setDropdownDisabled] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const dispatch = useDispatch();

  useEffect(() => {
    props.navigation.addListener("didBlur", () => {
      setSelectedGenre(null);
      setSelectedMood(null);
    });
    props.navigation.addListener("didFocus", () => {
      setIsLoading(true);
      if (isAudioPlaying) {
        dispatch(stopPlay(true));
      }
      setGenres([...new Set(songData.map(x => x.genre))]);
      setMoods([...new Set(songData.map(x => x.mood))]);
      setIsLoading(false);
    });
  }, []);

  useEffect(() => {
    selectedGenre === null
      ? setGenres([...new Set(songData.map(x => x.genre))])
      : setMoods([...new Set(filteredSongs.map(x => x.mood))]);
    if (selectedGenre === undefined || selectedGenre === null) {
      setStyleToggle();
    } else {
      setStyleToggle(styles.disabled);
    }
  }, [selectedGenre]);

  useEffect(() => {
    selectedMood === null
      ? setMoods([...new Set(songData.map(x => x.mood))])
      : setGenres([...new Set(filteredSongs.map(x => x.genre))]);
    if (selectedMood === undefined || selectedMood === null) {
      setStyleToggle();
    } else {
      setStyleToggle(styles.disabled);
    }
  }, [selectedMood]);

  const genreValueHandler = itemValue => {
    setSelectedGenre(itemValue);
    dispatch(filterGenre(itemValue));
  };

  const moodValueHandler = itemValue => {
    setSelectedMood(itemValue);
    dispatch(filterMood(itemValue));
  };

  const submitPress = () => {
    if (
      selectedGenre === null &&
      selectedMood === null &&
    ) {
      Alert.alert("Please enter a song name or choose a filter.");
    } else {
      dispatch(filterSong(selectedGenre, selectedMood));
      props.navigation.navigate({ routeName: "Songs" });
    }
  };

  return (
    <Gradient>
      <HeaderText>Filter:</HeaderText>
      <GenreDropdown
        style={dropdownStyle}
        selectedValue={selectedGenre}
        onValueChange={genreValueHandler}
        disabled={dropdownDisabled}
      />
      <MoodDropdown
        style={dropdownStyle}
        selectedValue={selectedMood}
        onValueChange={moodValueHandler}
        disabled={dropdownDisabled}
      />
      <MainButton name={"Submit"} onPress={submitPress} />
    </Gradient>
  );
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...